先赞后看,养成习惯!!! ^ _ ^ ❤️ ❤️ ❤️
码字不易,大家的支持就是我坚持下去的动力,点赞后不要忘记关注我哦
个人主页:伯明翰java
文章专栏:JavaSE
如有错误,请您指正批评 ^ _ ^
1. 继承
1.1 为什么需要继承
Java中将现实中具体的东西抽象成类,类经过实例化之后的产物对象,则可以⽤来表⽰现实中的实体。但现实中物与物之间存在一定的关联,那么设计程序过程中就要考虑类与类之间是否存在一定的联系
⽐如:狗和猫,它们都是⼀个动物。
使⽤Java语⾔来进⾏描述,就会设计出这样的代码:
// Dog.javapublicclassDog{Stringname;intage;floatweight;publicvoideat(){System.out.println(name+"正在吃饭");}publicvoidsleep(){System.out.println(name+"正在睡觉");}voidBark(){System.out.println(name+"汪汪汪~~~");}}// Cat.JavapublicclassCat{Stringname;intage;floatweight;publicvoideat(){System.out.println(name+"正在吃饭");}publicvoidsleep(){System.out.println(name+"正在睡觉");}voidmew(){System.out.println(name+"喵喵喵~~~");}}通过上述代码来看,猫与狗的类存在大量的代码重复
那能否将这些共性抽取呢?⾯向对象思想中提出了继承的概念,专⻔⽤来进⾏共性抽取,实现代码复⽤。
1.2 继承概念
继承:是Java中一种使得子类可以自动共享父类数据结构和方法的机制,是代码复用的重要手段,它允许程序员在原有类的基础上进行扩展。
继承主要解决的问题是:共性抽取,实现代码复用
1.3继承的语法
在Java中如果要表⽰类之间的继承关系,需要借助extends关键字
修饰符class⼦类extends⽗类{// ...}// Animal.javapublicclassAnimal{Stringname;intage;publicvoideat(){System.out.println(name+"正在吃饭");}publicvoidsleep(){System.out.println(name+"正在睡觉");}}// Dog.javapublicclassDogextendsAnimal{voidbark(){System.out.println(name+"汪汪汪~~~");}}// Cat.JavapublicclassCatextendsAnimal{voidmew(){System.out.println(name+"喵喵喵~~~");}}// TestExtend.javapublicclassTestExtend{publicstaticvoidmain(String[]args){Dogdog=newDog();// dog类中并没有定义任何成员变量,name和age属性肯定是从⽗类Animal中继承下来的System.out.println(dog.name);System.out.println(dog.age);// dog访问的eat()和sleep()⽅法也是从Animal中继承下来的dog.eat();dog.sleep();dog.bark();}}从上述代码我们可以看到Dog类和Cat类的部分代码重复使⽤了Animal中的代码。
1.4成员访问
在⼦类⽅法中或者通过⼦类对象访问成员时:
- 如果访问的成员变量⼦类中有,优先访问⾃⼰的成员变量。
- 如果访问的成员变量⼦类中⽆,则访问⽗类继承下来的,如果⽗类也没有定义,则编译报错。
- 如果访问的成员变量与⽗类中成员变量同名,则优先访问⾃⼰的。
成员变量访问遵循就近原则,⾃⼰有优先⾃⼰的,如果没有则向⽗类中找
⼦类中访问⽗类的成员⽅法:
- 成员⽅法没有同名时,在⼦类⽅法中或者通过⼦类对象访问⽅法时,则优先访问⾃⼰的,⾃⼰没有时再到⽗类中找,如果⽗类中也没有则报错。
- 通过派⽣类对象访问⽗类与⼦类同名⽅法时,如果⽗类和⼦类同名⽅法的参数列表不同(重载),根
据调⽤⽅法适传递的参数选择合适的⽅法访问,如果没有则报错;
1.5 super关键字
在一定场景下⼦类和⽗类中可能会存在相同名称的成员,如果要在⼦类⽅法中访问⽗类同名成员时,该如何操作?直接访问是⽆法做到的,Java提供了super关键字,该关键字主要作⽤:在⼦类⽅法中访问⽗类的成员
publicclassBase{inta;intb;publicvoidmethodA(){System.out.println("Base中的methodA()");}publicvoidmethodB(){System.out.println("Base中的methodB()");}}publicclassDerivedextendsBase{inta;// 与⽗类中成员变量同名且类型相同// 与⽗类中methodA()构成重载publicvoidmethodA(inta){System.out.println("Derived中的method()⽅法");}// 与基类中methodB()构成重写(即原型⼀致,重写后序详细介绍)publicvoidmethodB(){System.out.println("Derived中的methodB()⽅法");}publicvoidmethodC(){// 对于同名的成员变量,直接访问时,访问的都是⼦类的a=100;// 等价于: this.a = 100;b=101;// 等价于: this.b = 101;// 注意:this是当前对象的引⽤// 访问⽗类的成员变量时,需要借助super关键字// super是获取到⼦类对象中从基类继承下来的部分super.a=200;super.b=201;// ⽗类和⼦类中构成重载的⽅法,直接可以通过参数列表区分访问⽗类还是⼦类⽅法methodA();// 没有传参,访问⽗类中的methodA()methodA(20);// 传递int参数,访问⼦类中的methodA(int)// 如果在⼦类中要访问重写的基类⽅法,则需要借助super关键字methodB();// 直接访问,则永远访问到的都是⼦类中的methodA(),基类的⽆法访问到super.methodB();// 访问基类的methodB()}}注:子类不能访问父类用final修饰的方法、静态方法和private修饰的方法