继承的主要作用:我们使用继承主要是为了避免出现重复的定义,程序中如果出现多个地方有相同的定义,可以把相同程序提取出来定义为父类。
子类继承父类使用extends关键字,子类具备父类所有的属性和方法,包括私有方法,只不过子类对父类的私有方法和成员没有访问权限,除非父类对外提供了访问的接口(get、set)方法。
子类可以自己扩充行为,也可以对父类的方法进行重写。
--------------------------------------------------------------------------
多态与is-a:
继承除了可以避免重复定义行为外,还有一个重要的关系-is-a,理解了这种关系有利于我们对多态的理解。
假设我们开发一个RPG游戏,有三个类分别为Role、SwordsMan、Magician,这三类父类是Role,后两者为子类。我们看看以下代码是否能通过编译:
SwordsMan swordsMan=new SwordsMan(); Magician magician=new Magician();
上面的代码能通过编译,我们从右往左使用is-a关系来进行判断,右边是不是一种左边,看看是否能通过编译。SwordsMan是一种SwordsMan,Magician是一种Magician,代码逻辑没有问题。
Role role1=new SwordsMan(); Role role2=new Magician();
同理,我们判断SwordsMan是一种role,Magician也是一种role,逻辑上没有问题。
Magician magician=new Role(); SwordsMan swordsMan=new Role();
上面的代码能够通过编译吗?Role不一定是Magician,Role也不一定是SwordsMan,所以没有通过编译。
通过上面的三个例子我们可以知道,编译器会进行“是一种”判断,如果我们不想让第三种情况出现编译错误,我们可以使用向下转型,让编译器住嘴,表明我们想创建的Role就是向下转型的子类。代码如下:
Role role=new Magician(); Magician magician=(Magician)role;//向下转型
但是上面的向下转型可能会出现运行错误,是因为向下转型出现错误,代码如下:
Role role=new Magician(); SwordsMan swordsMan=(SwordsMan)role;
上面两行代码编译没有问题,但在运行时会报ClassCastException错误。
----------------------------------------------------------------------------------------------------------------------------------------------
什么叫做多态?
一种抽象解释是单一接口操作不同类型的对象,我们对一个接口方法定义得对象参数为一个父类,我们传入的参数可以为父类的任何子类,但是不同的子类对象会有不同的行为发生。这就是多态。
有关于多态的知识点可以参考这篇博文:
https://www.cnblogs.com/xdp-gacl/p/3644035.html
父类的引用访问不了子类的成员,只能够访问子类的重写方法。