【JavaSE】继承与多态的理解与区别

@

抽象类的特点:

	A:抽象类和抽象方法必须用abstract关键字修饰
	B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
	C:抽象类不能实例化
		因为它不是具体的。
		抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?
		用于子类访问父类数据的初始化
	D:抽象的子类
		a:如果不想重写抽象方法,该子类是一个抽象类。
		b:重写所有的抽象方法,这个时候子类是一个具体的类。

抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
Animal a = new Cat();

多态其实主要用于 抽象类和其具体子类。而不是具体类和具体类之间。

抽象类和接口的区别:

A:成员区别
抽象类:
	成员变量:可以变量,也可以常量
	构造方法:有
	成员方法:可以抽象,也可以非抽象
接口:
	成员变量:只可以常量  默认public static final
	成员方法:只可以抽象  默认public abstract
	
B:关系区别
类与类
	继承,单继承
类与接口
	实现,单实现,多实现
接口与接口
	继承,单继承,多继承
	
C:设计理念区别
抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。

为什么new子类要先执行父类构造方法

其实之前一直不明白构造函数“初始化”的含义。一直以为 “初始化”==“变量赋值”,其实初始化的内涵不是这样的。

class Person{...}
class Student extends Person{...}

对于Student stu = new Student(),更合理的解释是:

1, 加载class文件

	5, 父类静态变量加载到方法区
	6, 父类静态代码块初始化变量
	7, 子类静态变量加载到方法区
	8, 子类静态代码块初始化变量

2, 加载main方法在栈内存中(类被加载后,虚拟机再调用静态方法main。类加载会先走静态代码块,注定静态代码块	先于main)
3, 在栈内存中开辟空间给Student stu(对象引用的空间)
4, new申请堆内存空间(对象的空间)


9, 父类变量默认初始化、显示初始化(一般只有默认初始化,创建一个学生类时不会直接写age=20,这样以后每个创建的对象一开始就20岁)
10, 父类构造代码块初始化(如果有赋值语句)
11, 父类构造器初始化(如果有赋值语句)

12, 子类变量默认初始化、显示初始化(一般只有默认初始化,创建一个学生类时不会直接写age=20,这样以后每个创建的对象一开始就20岁)
13, 子类构造代码块初始化(如果有赋值语句)
14, 子类构造器初始化(如果有赋值语句)

最后,把对象地址赋值给stu

详见:

http://bbs.csdn.net/topics/380077372
http://www.jb51.net/article/37881.htm
http://bbs.csdn.net/topics/260013819

多态的弊端及解决办法

弊端:Fu f = new Zi() f不能用子类特有方法。

解决办法: Zi z = (Zi)f; 由于本身是子类对象,可以向下转型会子类引用,再调用子类特有方法。

继承和多态中成员访问的特点总结

继承是站在子类的角度,多态是站在父类的角度。

继承时,子类为观察者,发起者。不论是成员变量还是成员方法,都是遵照就近原则。
子类变量会被优先调用。
而子类方法会覆盖父类方法。
所以,同名情况下,子类都先使用自己的。




多态中,父类为观察者,发起者。
父类自己的变量会优先调用,而且不存在调用子类变量的情况。因为,调用子类变量说明变量名不同,说明是子类后加上去的。父类中是没有get该变量的方法的!
父类方法会被子类方法覆盖。
所以同名曲情况下,父类使用自己的变量,使用子类的方法。



实际开发中,使用继承一般更多的是为了复用性,为了重写父类方法。很少涉及变量(子类自己的)。
    使用多态一般更多的是为了可维护性,为了同一个引用调用不同子类的特有同名方法。很少涉及变量(父类自己的)。
posted @ 2020-07-01 22:01  bluepopo  阅读(1975)  评论(0编辑  收藏  举报