07、面向对象特征之多态&内部类

面向对象特征之多态&内部类

1、定义

  某一类事物的多种存在形态。

  对象的多态性,就是一个对象对应着不同类型

      例子:动物中猫,狗

    猫这个对象对应的类型是猫类型

        猫 x = new 猫();

    同时猫也是动物中的一种,也可以把猫称为动物

        动物 y = new猫();

    动物是猫和狗具体事物中抽取出来的父类型;

    父类型引用指向了子类对象。

 

2、多态在代码中的体现:

  *父类或者接口的引用指向了其子类的对象。

多态举例:毕老师和毕姥爷的故事。

class 毕姥爷{

    void 讲课(){

        System.out.println("管理");

    }

    void 钓鱼(){

        System.out.println("钓鱼");

    }

}

class 毕老师 extends 毕姥爷{

    void 讲课(){

        System.out.println("Java");

    }

    void 看电影(){

        System.out.println("看电影");

    }

}

class  DuoTaiDemo{

    public static void main(String[] args){

        // 毕老师 x = new 毕老师();

        // x.讲课();
    
        // x.看电影();

 

        毕姥爷 x = new 毕老师();
    
        x.讲课();//讲课执行的毕老师的方法“Java”

        x.钓鱼();

 

        毕老师 y = (毕老师)x;

        y.看电影();

   }

}

 

 

3、多态的好处:

  *提高了代码的扩展性,前期定义的代码可以使用后期的内容。

  *提高了程序的后期可维护性。

 

4、多态的弊端:

     前期定义的内容不能使用(调用)后期子类的特有内容

 

5、多态的前提:

  *需要存在继承或实现关系

  *要有覆盖操作

 

6、多态的特点:

  *成员变量

     只看引用变量所属的类。

     编译时:参考引用型变量所属的类中是否有调用的成员变量,有,编译通过,没有,编译失败。

     运行时:参考引用型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量。

     简单说:编译和运行都参考等号的左边。

 

  *成员函数(非静态)

    编译时:参考引用型变量所属的类中是否有调用的函数。有,编译通过,没有,编译失败。

    运行时:参考的是对象所属的类中是否有调用的函数。

    简单说:编译看左边,运行看右边。

    因为成员函数存在覆盖特性。

 

  *静态函数

    编译时:参考引用型变量所属的类中是否有调用的静态方法;

    运行时:参考引用型变量所属的类中是否有调用的静态方法。

    简单说:编译和运行都看左边。

    其实对于静态方法,是不需要对象的。直接用类名调用即可。

   除了成员函数(非静态)是编译看左边,运行看右边,其他都是编译运行都看左边。

 

7、转型(重点掌握)

  (1)多态:

          向上转型,作用是限制对特有功能的访问,隐藏子类

          向下转型,目的是为了使用子类中的特有方法。

 

  (2)注意:对于转型,自始至终都是子类对象在做着类型的变化。

    instanceof:用于判断对象的具体类型,只能用于引用数据类型判断,通常在向下转型前用于健壮性的判断。(由instance和of两个单词组成)

 

    Animal a = new Cat();//自动类型提升,猫对象提升了动物类型。但是特有功能无法访问。

    作用就是限制对特有功能的访问。

    专业讲:向上转型。将子类型隐藏,就不用使用子类的特有方法。

    Cat c = (Cat)a;//如果还想用具体动物猫的特有功能,可以将该对象进行向下转型。

    向下转型的目的是为了使用子类中的特有方法。

 

8、内部类:

  (1)将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类);

    (2)内部类访问特点:

    *内部类可以直接访问外部类中的成员,包括私有成员

    *外部类要访问内部类,必须建立内部类的对象。

 

  (3)内部类的位置:

    *内部类定义在成员位置上

      **可以被private static成员修饰符修饰

      **被static修饰的内部类只能访问外部类中的静态成员。

    *内部类定义在局部位置上

      **也可以直接访问外部类中的成员;

      **同时可以访问所在局部中的局部变量,但必须是被final修饰的(因为局部变量若没被final修饰,会用完就释放,这样内部类就不能访问了)

 

  (4)作用:一般用于类的设计。

    分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容,这时就把还有的事物定义成内部类来描述。

    如果内部类是静态的,相当于一个外部类

    如果内部类中定义了静态成员,内部类必须为静态

 

    为什么内部类能直接访问外部类中的成员呢?

      那是因为内部类持有了外部类的引用。外部类名.this

代码示例:

 

class Outer{

    int num = 3;

    class Inner{

        int num = 4;

        void show(){

            int num = 5;

            System.out.println(Outer.this.num);

        }

    }

    void method(){

        new Inner().show();

    }

}

 

  

(5)匿名内部类:就是内部类的简写格式

  *必须有前提:

    匿名内部类必须继承或者实现一个外部类或者接口。

  *格式:new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容)}

 

  *匿名内部类:其实就是一个匿名子类对象。

      简单理解:就是建立一个带内容的外部类或者接口的子类匿名对象。

 

  *什么时候使用匿名内部类呢?

       通常在使用方法是接口类型参数,并该接口中的方法不超过三个时,可以将匿名内部类作为参数传递,增强阅读性。

原文地址:https://www.cnblogs.com/zyh-blog/p/3162549.html