赞
踩
继承作为面线对象的第二大特性。下面我们来详细了解一下。
定义:如果一个类别B“继承自”另一个类别A,就把这个B称为“A的子类”,而把A称为“B的父类别”也可以称“A是B的超类”。继承可以使得子类具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类追加新的属性和方法也是常见的做法。 一般静态的面向对象编程语言,继承属于静态的,意即在子类的行为在编译期就已经决定,无法在执行期扩展。
定义:使用private将属性进行封装(这个属性只能在当前类的内部可见,对外部隐藏)
特性:保护性,易用性(用过程序对外提供的方法来操作属性->汽车启动,电脑启动)
例子:人类->心脏,汽车->发动机
复习:什么是方法重载?
前提:在同一个类中,定义了若干个方法名称相同,参数列表不同,与返回值无的一组方法,这样的一组方法称之为方法重载。
代码示例:
在一个animal包中创建三个类封分别是 Animal,Dog,Cat。
在测试类Test类中进行测试。
//输出结果:
动物正在吃食物
修勾正在吃狗粮
上面三个类中的的代码完全一样,这三个类,按道理来说,所有Animal类都应该具备name属性以及eat方法。
//Dog is animal
//修勾 是 动物
//Cat is animal
//修某 是 动物
拓展:
大家以后进公司
写完一个功能之后,你的代码能跑起来是第一步。第二步,Code Review -> 你的项目组的其他安成员在你写完代码之后,大家会开会,一起来看你的代码存在啥问题或者可以优化的点,尤其是阿里,所有的代码都不允许重复出现(一行都不行)。如果出现了重复你的代码一定可以优化。
上面的代码存在一定问题,就是这三个类中的有部分代码都是重复的,虽然功能上没问题,但是很不规范也浪费资源,那么怎么解决这个问题呢,这也就是Java面向对象编程的第二大特性——继承。
当类和类之间满足,一个类 is a 另外一个类,一定存在继承关系,天然继承。
Bird is an Animal
Duck is an Animal
此时Dog,Cat,Bird都应该是Animal的子类
当一个类继承了另一个类,另一个类中所有的属性和方法,子类就天然具备了。
Java中使用 extends 关键字表示类的继承。
例如,将上面代码优化只需要进行如下操作:
用法 :在Cat 后边使用extends关键字 继承Animal类,这样Cat机会天然继承Animal中所有的属性和方法,不需要再去写那些重复的代码。
其中Cat叫做 子类/派生类,Animal叫做 父类/基类。
注意:
不能为了省略代码就简单使用继承,要想使用必须满足 is a 关系
比如:
Person extends Dog{}; 不能这样继承,因为 Person is not a Dog
不满足is a 关系千万不能使用继承!!!
继承的规则:
1.要能使用继承必须满足is a 关系
2.一个子类只能使用extends继承一个父类。(单继承)Java中不允许多重继承,extends后面只能跟一个父类。但是Java中允许多层继承,没法当儿子,可以当孙子~~
3.子类会继承父类的所有属性和方法,显示继承(public属性和方法可以直接使用),隐式继承(private属性和方法),子类其实也继承了这个属性和方法。都是无法直接使用。
比如下列代码,我再创建一个Taidi这个类,我想继承Animal和Dog这两个类,此时就是不行的,编译器会报错
但是可以多层继承,即Taidi既是Animal的子类又是Dog的子类。
从上到下满足树状继承关系,满足继承关系的类之间一定是逻辑上的垂直关系。
定义:子类无法通过直接使用该方法或者属性,必须通过父类提供的方法来操作。
举个现实生活中的例子:
你知道你爸银行卡的余额不? 你能否自由支配你爸的钱,想咋花咋花
你肯定是继承你爸了,但是余额这个属性对于父类来说就是一个私有属性
你肯定继承了,但是无法随心所欲的支配这个属性,必须通过父类提供的方法来操作属性你爸每个月给你打1000RMB,如何证明你确实继承了你爸的余额属性??答:为啥你爸的钱不打给我?哈哈哈哈哈哈
代码示例:
在Animal类中定义一个private权限的age属性
//age 这个属性只能在 Animal 这个类的内部可见。
//子类其实也继承了,但是没法直接用
//在Test类中无法访问到
需要使用Animal类提供的getter和setter方法访问:
在Animal类中生成getter和setter方法
此时就可以在Test类中访问了
作用域:protected作用域不同包中的子类可见。
举个栗子,将上面的代码中Animal类的name属性权限改为protected,此时name属只能在Animal的不同包的子类可见。
代码示例:
再创建一个新的包命名为person,在person中创建一个Person类 ,此时就可以直接访问name属性。
举个现实中的例子去理解protected权限
身体发肤受之父母,在你这个类的内部,你的血液,你的器官当前类的内部可以使用的。
对于我来说,我就是另外和你父母没有任何关系的类你的血液,器官也罢对于我来说就是不可见的。
四访问权限修饰符到这里就介绍而完毕了。
private < default < protected < public
那么protected权限在同包中没有继承关系的类之间是如何?
既然protected权限>包权限,包权限可见的范围,对protected来说—定包含。
即,同包下(同级目录,不包含子包)的没有关系的类之间以及不同包的有继承关系的类之间可见的。
要产生一个子类对象,默认首先产生一个父类对象。
编译器默认调用父类的构造方法产生父类对象,在调用子类的构造方法产生一个子类对象。
表示直接从父类中去寻找同名属性
新建一个包,包下创建一个Person类和一个China类,
当有继承关系时候,this关键字默认在当前类中寻找同名属性,若没找到,继续向上寻找父类中的同名属性。
直接使用name,编译器默认都是使用this.name
要是现在就想访问父类中的name属性,就要用到super关键字,只需要将fun方法中的this.name 改成 super.name 即可。直接从Person父类中寻找同名属性。
问题:如果Person还有父类怎么办?
答:super先从直接父类中寻找同名属性,若不存在再向上寻找 ,this直接从当前类中寻找同名属性,若不存在再向上搜索。
举个栗子:
不能使用super关键字直接调用private权限的属性。
1.修饰构造方法
super(父类构造方法的参数)
super();//直接父类的无参构造,可写可不写
若父类中不存在无参构造,则子类构造方法的首行必须使用super的有参构造。
在一个构造方法中,无法显式使用this()和super()同时出现。
2.super修饰普通方法:
和修饰属性,直接从父类中寻找同名方法。
和属性的使用是一模一样的~~
super关键字不能指向当前父类的引用。但是this可以!!这点是有区别的~~
final 修饰属性表示属性的值不能变,常量。(值定义以后无法修改)
final 修饰类,表示这个类无法被继承。(final class Person ,表示这个类无法被继承)
String类就是final类,没有子类无法被继承。
类和类之间除了继承关系
类A is a 类B -> 类A继承于类B
Dog extends Animal
还有组合关系 has a
class School {
Student student;
Teacher teacher;
}
//School has a student
//School has a teacher
未完待续…………
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。