继承
面向对象中,为什么要使用继承?
我们来设想这么一个场景:你是一个宠物店的老板?现在你要为以下四种动物的行为录入到管理系统中
四中动物分别有以下行为
布偶猫:吃饭,喝水,抓老鼠
狸花猫;吃饭,喝水,抓老鼠
哈士奇;吃饭,喝水,看家,拆家
泰迪;吃饭,喝水,看家,蹭一蹭
观察四种动物的行为可以发现,如果你单独的为一个个宠物手动输入方法,你会发现:是不是每个动物的行为中,都有吃饭,喝水这两个基本行为。所以,是不是有那么一种功能的实现,能减少我们手动输入的代码量,减少一些重复的代码功能呢?答案是有的--继承
继承的定义:
当多个类中存在相同属性和行为时,将这些相同的内容抽取到一个单独的类(父类)中,这些多个类无需再定义这些属性和行为,只要去继承那一个单独的类即可。我们称这些多个类,为子类
继承的理解
- 孩子的长相,性格,有一部分是很父亲极其相似的,我们便说,孩子继承了父亲的基因,但孩子又和父亲有不同的地方,我们便说,这是孩子特有的性格。
- 在Java继承中,亦是如此,子类继承了父类的功能,而子类,又可以构造出新的方法和成员变量增添新的功能
继承的使用
依旧拿上面的宠物店例子:
classDiagram
Animal <|-- dog
Animal <|-- cat
Animal <|-- other
Animal :
Animal :
Animal:
Animal:
class dog{
+
}
class cat{
-
}
所以我们创造一个父类-Animal.
创造下面方法
public class Anminal{
public void eat(){
System.out.println("吃东西");
}
public void drink(){
System.out.println("喝水");
}
}
创造子类---cat和Dog
现在将子类继承父类
public class Cat extends animnal{
public void eat(){
System.out.println("抓老鼠")
}
}
public class Dog extends animanl{
public void lookhome(){
System.out.println(“看家”)}
}
我们就完成了第一个子类继承父类的创建了
但观察发现,布偶猫和狸花猫,也是猫类,且都有抓老鼠的行为。
所以我们便可以再创造这两个的子类,去继承Cat这一父类
接着创造buoucat(布偶猫)--子类
public class buoucat extends Cat {
}
创造(狸花猫)lihua_cat--子类
public class buoucat extends Cat {
}
类比得,我们可以创造哈士奇和泰迪两个子类去继承Dog这一个父类
创造哈士奇Husky---且创造一个拆家的方法
public class Husky extends Dog {
public void breakhome(){
System.out.println("拆家)
}
}
创造泰迪tity---且创造一个蹭一蹭的方法
public class tity extends Dog {
public void touch(){
System.out.println("蹭一蹭")}
}
这样,我们已经实现了使用继承来输入宠物信息的方法了。
继承的使用事项
/**
* 父类的构造方法不能被子类继承
*父类中的成员变量能被子类继承---如果父类中成员变量有private修饰,则需要通过get-set方法获取
*子类能继承成员方法中的虚方法表,如果有private修饰则不能
*Java中只支持单继承,不支持多继承
*子类继承的父类称为直接父类,间接继承称为间接父类。最大的父类是Object
* */
继承中的方法重写
实际应用中,由于父类的方法需求不能完全满足子类需求,我们往往进行方法重写
- 在子类中,可以根据需要对从父类中继承来的方法进行方法重写。重写以后,当子类对象调用与父类的同名同参数的方法时,优先调用子类重写的方法。
- 采用@Override,放在重写方法的上面,用来校验重写方法是否正确
- 父类是void类型,子类继承重写也是void
- 子类能写的都是非staitc的方法
- 子类的返回值类型要小于父类的返回型类型(不可能儿子比爸爸大对吧)
- 子类的访问权限要大于父类的访问权限(因为这样才可以调用父类)
继承中的成员变量
public class Fu()
{
String name =“张三”
}
public class Zi extends Fu{//访问成员变量时,遵循就近原则
String name="李华";
public void zishow(){
String name="凝光";
System.out.println(name);//就近
System.out.println(this.name);//指向子类中的类
System.out.println(super.name);//指向父类
}
}
* 重名时就近原则,但this优先指向类中,super指向父类
*即先在局部找,再在本类找,最后在父类找,逐层向上
super与this的区别
- super()函数在子类构造函数中调用父类的构造函数时使用,而且必须要在构造函数的第一行。
- 但我们一般省略super,除非需要父类的成员变量。
- this()函数调用本类中另一种形成的构造函数。this()只能用在构造函数中,并且也只能在第一行。
- super()和this()都指的是对象,不能同时出现在构造函数里,只能二选一,均不可在static环境中使用。
- super:引用当前对象的父类中的成员。语法格式:super.属性名/方法名()
- this:代表当前对象名。this是对象的隐藏属性 (本质就是一个普通的成员变量),和其他non-static 属性一样,在创建对象的时候会为每个新对象分配该对象的专属成员变量(this就是其中一个), 在继承中,指向这个类中的成员变量
- this代表本类对象的引用,super指向父类的内存空间。(无就默认指向Object)
继承的好处
1.减少了重复代码的量,耦合度高。 2.能在父类的基础上,创造出更多功能的子类方法。