Java面向对象 ----多态

java的第二部分 面向对象————多态
4.1面向对象的第三个特征:
多态定义:
多态可以理解为某一类事物的多种存在形态。
例如: 人 可以分为 男人 女人
动物 猫 狗 等
粮食 大米 小麦等
举例
例:动物中猫,狗。
猫这个对象对应的类型是猫类型
猫 x = new 猫();
同时猫也是动物中的一种,也可以把猫称为动物。
动物 y = new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向了子类对象。
从四个方面对多态进行学习:
1)多态的体现
父类的引用指向了自己的子类对象。 // Anmial a = new Cat();
或者称作是 父类的引用接收自己的子类对象。

abstract class Anmial {
    public abstract void eat();
}

class Cat extends Anmial
{
    public void eat() {
        System.out.println("吃鱼");
    }

    public void catchMouse() {
        System.out.println("逮老鼠");
    }
}
public class DuoTaiDemo {
    public static void main(String[] args) 
    {

       // Anmial c = new Cat();
        //c.eat();
        funcation(new Cat());
          }
          public static void funcation(Anmial a) 
              {
                     a.eat();
              }
     }

2)多态的前提
(类与类之间要有关系)
1、需要存在继承或者实现关系
2、要有覆盖操作
3)多态的好处
多态的存在提高了程序的扩展性和后期可维护性。
4)多态的弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5)多态的应用
多态 - 转型
类型的提升:
引用数据类型 (类类型)
Animal a = new Cat (); 类型提升 也称为向上转型(转成父类型)
如果想调用猫的特有方法时怎么办呢?
强制将父类的引用转成子类类型。
Cat c= (Cat)a;
4.1.2多态中成员的特点:
成员函数:
多态中非静态成员函数的特点:编译时:要查看引用型变量所属的类中是否有所调用的方法。如果没有,编译会失败。
编译看左边,运行看右边。
在运行时: 要查看对象所属的类中是否有所调用的成员。(若是子类中也有该方法那么就会将父类中的方法覆盖掉)

class Fu6 {
    public void method1() {
        System.out.println("Fu method1");
    }

    public void method2() {
        System.out.println("Fu method2");
    }

}
class Zi6 extends Fu6 
{
    public void method1() {
        System.out.println("zi method1");
    }

    public void method3() {
        System.out.println("zi method3");
    }
}

public class DuoTaiDemo2 {
    public static void main(String[] args) 
        {  Fu6 f = new Zi6();
           f.method1();   //此时  结果是:zi method1

           f.method2(); //   结果是:Fu method2    子类继承了父类的方法。

          // f.method3();   //此处编译会失败  原因引用变量所属的类中没有该方法。
        }

}

在运行时: 要查看对象所属的类中是否有所调用的成员。(若是子类中也有该方法那么就会将父类中的方法覆盖掉)

 Fu6 f = new Zi6();  //父类的引用指向了自己的子类对象   多态
   f.method1();  //   结果是: zi method1

多态中成员变量的特点:
无论编译还是运行只看引用变量所属的类。

class Fu6 {
    int num =6;
    public void method1() {
        System.out.println("Fu method1");
    }

    public void method2() {
        System.out.println("Fu method2");
    }

}
class Zi6 extends Fu6 
{
    int num =7;
    public void method1() {
        System.out.println("zi method1");
    }

    public void method3() {
        System.out.println("zi method3");
    }
}

public class DuoTaiDemo2 {
    public static void main(String[] args) {
        Fu6 f = new Zi6();     
        System.out.println(f.num);  //  结果是 6
        Zi6  z =  new Zi6();
        System.out.println(z.num);   //   结果是  7

静态函数被调用时时只参考引用型变量所在的类即可。
4.2 内部类
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。

class Outer{
    int x = 3;
    class Inner
    {
      int y =6;
      void show(){}
    }
   void  funcation(){}
}

访问规则:
内部类可以直接访问外部类中的成员,包括私有成员。
(原因是内部类中持有一个外部类的引用格式是 外部类名.this)
而外部类要访问内部类中的成员必须要建立内部类的对象。


class Outer {
    private int x = 0;
    int y = 5;

    class Inner {

        void show()

        {
            funcation();   //内部类可以直接访问外部成员 包括私有的
            System.out.println("内部类" + x);
        }

    }

    void method() {
        Inner in = new Inner();   //外部类要访问内部类需要建立内部类对象
        in.show();
    }

    public void funcation() {
        System.out.println("外部类" + y);
    }
}

public class InnerDemo {
    public static void main(String[] args) {
        Outer ot = new Outer();
        ot.method();  
        }        //  结果是:   外部类5
                              内部类0              
}                                         

内部类的位置:
内部类定义在成员位置上 可以被private static成员修饰符修饰。
被static修饰的内部类只能访问外部类中的静态成员。

class Outer {
    private static  int x = 0;
    static int y = 5;

    private static  class Inner    //   private static  成员修饰符修饰   
{ 
         int x =3;
        void show()

        {    int x = 6 ;
            funcation();    //   被static修饰的内部类只能访问外部类中的静态成员            
            System.out.println("内部类" +Outer.this. x); //  被static修饰的内部类只能访问外部类中的静态成员
        }   //  注意x处啥也不加默认走的是最近的x,6局部的;加上this走的是该类成员处本类对象的引用 3。加上Outer.this走                                                                                
                                                             的是外部的成员变量。
    }

    void method() {
        Inner in = new Inner();
        in.show();
    }

    public static void funcation() {
        System.out.println("外部类" + y);
    }
}

public class InnerDemo {
    public static void main(String[] args) {
        Outer ot = new Outer();
        ot.method();

    }

}

直接访问内部类成员的格式(内部类不能私有和被静态修饰)
Outer.Inner in = new Outer().new Inner();
in.show();
内部类定义在局部位置上:
也可以直接访问外部类中的成员。
同时可以访问所在局部中的局部变量,但必须是被final修饰的。


class Outer {
    private static int x = 0;
    static int y = 5;

    public static void method() {
         final int x= 9;      
        class Inner {

            void show(){

                funcation();
                System.out.println("内部类" +x); // 局部变量处的局部变量必须被final修饰否则编译会失败(以免产生安全隐患)。                                                                                                                                                                  

          }

        Inner in = new Inner();      //在此处类的下面创建内部类对象,在类的上面Jvm编译会报错,认为没有类就new对象。
        in.show();
    }

4.2.1匿名内部类
匿名内部类是内部类的简化写法。(其实也就是没名字的内部类)
(思考匿名内部类没类名的话内部类的对象怎么创建呢?)
其实匿名内部类就是一个匿名子类对象
**定义匿名内部类的前提是:
内部类必须继承或实现一个外部其他类或者接口。**
创建一个外部其他类的对象(当外部其他类是抽象类是要覆盖其方法的(抽象类不能被直接创建对象))
匿名内部类的格式: new 外部其他类名或者接口(){ 定义子类的内容 (覆盖类 或者接口的代码) }

abstract class AbsDemo 
{
    abstract void show();
}
class OuterDemo {
    private int x = 5;
    int y = 3;
    void funcation() {
        new AbsDemo()                 ////new Inner().show();  这部分其实就是匿名内部类对象
        {
            void show ()
            {
                method();
                System.out.println("show:::"+x);
            }
        }.show();
}
      public void method()                                
      {
        System.out.println("外部类" + y);
      }
}

public class NIMingDemo {
    public static void main(String[] args) {
        OuterDemo ot = new OuterDemo();
         ot.funcation() ;

    }

}

匿名内部类的演化进程就是下面的内部类继承一个外部其他类缩写。

/*class Inner extends AbsDemo

    {
        public void show() {
            method();
            System.out.println("show::" + x);
        }
*/

记住:其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖,一个带内容的子类对象。
匿名内部类可以用 父类名 引用型变量 = new 父类的子类对象;匿名内部类的多态。

abstract class AbsDemo {
    abstract void show();
}
class  Outer{
void funcation() 
    {
        //new Inner().show();
    AbsDemo a = new AbsDemo()
    {
            void show ()
            {
                method();
                System.out.println("show:::"+x);

            }
            void jjK()
            {  
         System.out.println("hahh");

            }

    };   // 记住此处是个分号         AbsDemo  a   =   new  Inner();  多态

      a.show();
      //a.jjk();     //此处编译是失败的,多态 父类中没有此方法编译失败。
      }

匿名内部类的应用:

interface Inter
{
    void mehod();
}
class Test
{   //  补足代码根据下面的语句
    public static Inter funcation()
    {
         return  new Inter()
         {
            public void method()
            {
                System.out.println("method run");
              }
         };

     }
}
class TestDemo
{
    public static void mian(String[] args)
    {
        Test.funcation().method();

    }

}

匿名内部类作为参数传递:

interface Inter
{
    void method();
}
public class InnerDemo2 {
    public static void main(String[] args)
    {
        show(new Inter()
        {
            public void  method()
            {
                System.out.println("method run");
            }
        });             //直接调用 静态方法 show (主函数是静态的)

}
     public static void show (Inter in)
     {
           in.method();
     }  


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值