毕向东Java视频学习笔记【Day10 多态+内部类】

倾然丶 夕夏残阳落幕 提交于 2019-11-26 22:04:27

Java_Day10 多态+内部类  


.01

.02

多态

x = new 猫();

动物 x = new 猫();

一个对象对应着不同类型。

多态在代码中的体现:父类或者接口的引用指向了其子类的对象。

.03

多态的好处:提高了代码的扩展性,前期定义的代码可以使用后期的内容。


100(animal a)使代码简单,其下面的两个method就可以省略 ,这是多态性的使用。

.04动态的弊端

前期定义的内容 不能调用后期子类中的特有内容。


84行会出现错误,因为animal中没有catchMouse的方法

多态的前提:1:必须要有关系,继承,实现。

2:要有覆盖。


.05转型

猫提升为动物 只能使用动物类中的方法,如果做eat这个动作,调用的是子类猫中的吃,因为子类中与父类有相同的eat方法,而子类覆盖了父类的eat方法(覆盖只发生在函数上,不发生在变量上)

专业讲:向上转型。将子类型隐藏。就不用使用子类的特有方法。除非父类子类有同样的方法,子类会覆盖父类,执行子类中的方法)


Animal a强制转换为(cat) 即向下转型

但是a创建时必须是cat型 如果是animal a = new animal()或者new成其他dog型等,a不能强转成cat

错误例子:


Classcastexception 类转换错误

 

对于转型,自始至终都是子类对象在做着类型的变化。

 

.06转型

.07多态类型判断

 

Main函数中将dog向上转为了animal

调用method时,如果用a.catchMouse()语句会出现错误

因为dog不是cat,没有catchmouse这个方法

所以必须进行判断

If(a instanceof Cat) 如果对象a传进来之前本身是cat则进行判断,如果是 进入if语句

才能再调用cat中的catchmouse方法

 

 instanceof:用于判断对象的具体类型。只能用于引用数据类型判断

通常在向下转型前用于健壮性的判断。

 

.08多态_成员变量

多态时:

成员的特点:

1.成员的变量。

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

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

c) 编译和运行都参考等号的左边。

 

解释c(面试中会考察,实际应用中很少出现这种情况,作为了解)

 

运行26行,输出3

看等号左边,23行定义是:

Fu f =  ,是父类中的 所以Num输出的是Fu中的Num  3

如果23行等号左边是是:Zi f = ,则输出4

 

另外:如果等号左边是Zi f =,而子类中没有定义成员变量即://int num =4;

那么f.num会调用父类的num,如果父类中的Num也没有,那么就会出现a)编译失败

 

 

                                        

 

 

 

 

 

 

 

 

.09多态_成员函数

 

2.成员函数(这是非静态,依靠对象有关)

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

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

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

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

 

28行中的f.show输出的是zi show也就是调用子类的show,其实是应该先用父类的show但是子类父类都有相同的方法,子类覆盖了父类的show,所以执行输出的是zi show,但是如果父类中没有show()方法,则编译失败。

编译的时候看的等号左边。Fu f = ,如果父类中没有show,那么编译失败。

如果子类没有show方法,则用父类的show

                   Fu f =   new Zi();

等号左边:引用型变量    等号右边:对象所属类

 

.10多态_静态函数

静态函数(静态,跟类有关,一创建就有所属了,叫做静态型绑定,跟对象无关)

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

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

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

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

 

.11内部类

内部类访问特点:

1.内部类可以直接访问外部类中的成员。

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

一般用于类的设计。

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

 

.12内部类——修饰符(不常见)

Class outer

{

Class inner

}

 Outer.inner a = new outer().new inner();

Class outer

{

Static Class inner//如果是静态内部类,相当于外部类

}

Outer.inner in = new outer.inter();

 

 

如果内部类都是静态的,成员是静态的。

Outer.inner.方法();

 

当内部类如果内部类定义了静态成员,该内部类必须被静态修饰

 

.13内部类-细节

 

 

11行如果是system.out.println(num);输出5

如果是system.out.println(this.num);输出4

如果是system.out.println(outer.this.num);输出3

 

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

因为内部类持有了父类的引用  外部类名.this

 

.14局部内部类

内部类可以放在局部位置上。可以放到for循环里面。

 

 

如果内部类在局部位置method里面,new内部类对象的时候,要跟内部类在同一局域内,并且必须在内部类的下面,不能在内部类的上面。

12行,必须定义成final

 

原理:内部类在局部位置上,只能访问局部中被final修饰的局部变量。

 

 

 

.15匿名内部类

内部类的简写模式

必须有前提:内部类必须继承或者实现一个外部类或者接口。

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

 

34-40就是匿名内部类  代替了23-29行内容

格式:new 父类or接口(){子类内容}

.16匿名内部类-应用

 

通常的使用场景之一:

当函数参数是接口类型时,而且接口中的方法不超过三个。

可以用匿名内部类作为实际参数进行传递

 

.17匿名内部类—细节

 

.18对象的初始化过程

 

New对象时,到子类的构造对象中,第19行,有个隐藏的supersuper只默认存在于子类构造函数中),再运行到父类的无参构造函数,父类无参构造函数中有一个show()方法,这时因为子类也有show()方法 会覆盖父类show ,所以执行子类中的show,此时num=9还没有运行,说明new对象时,先默认初始化0,再进行构造函数初始化的super内容,之后,回到子类的无参构造函数,再进行第17行的显示初始化,再执行20行。

 

 

Super()是直接转到父类的无参构造函数?是的

 

 

New Zi();

1.子类默认初始化0

2.子类无参构造函数中的super->父类的无参构造函数

3.父类无参构造函数super(到object,但是无作用)

4.  11行 显示初始化num=9;

5.  12行 打印Fu

6.  13show但是子类有show覆盖父类的show输出32行的zi show

(注意:虽然父类显示初始化num=9 ,但是回到子类的show num还是0)

7. 第27行显示初始化num=8

8. 构造代码初始化 输出22Zi

9. 第28行,再次调用子类show输出zi show...8


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!