目录
- 继承
- 一.什么是继承
- 二.为什么要使用继承
- 三.继承的语法
- 四.继承中有重复怎么办?
- 1.**访问原则**
- ==五.super和this==
- 1.**this**
- 2.**super**
- 3.**super注意事项**
- 4.**super和this异同点**
- 六.构造方法的引入
- 1.父类不带参数的构造方法
- 2.父类带有参数的构造方法
- 七.继承中的执行顺序
- 八.继承方式
- 九.final
- 十.组合
继承
一.什么是继承
是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用。
二.为什么要使用继承
在日常写代码的过程中,有时会敲写很多重复的代码,让自己的代码冗长无味,降低了可读性。当我们使用继承时,代码就变得简洁明了,更加美观。减少无用代码,提高开发效率。
我们举一个例子来说明:
我们在编写程序时,遇到一类相同的物时,通常需要挨个定义,如下
编写狗类时,我们需要狗拥有名字,年龄,毛色等的属性,也需要eat()等成员方法,以便后续使用
编写猫类时,我们也需要猫拥有名字,年龄,毛色等属性,也同样需要eat()等方法
这时我们发现狗和猫有许多重复的定义(共性)–名字,年龄,eat()等…
那我们可不可以使用一种语法来减少重复呢?这时就发明了继承。
三.继承的语法
修饰符 class 子类 extends 父类 {派生类基类超类}
使用关键字extends来构写继承。
以猫和狗为例子,它们都属于动物,所以我将共性的类名称作Animal
//动物类——共性class Animal{public String name;public int age;public String color;public void eat(){System.out.println(this.name+"正在吃饭");}}//狗类class Dog extends Animal{public float weight;public void barks(){System.out.println(super.name+" 汪汪汪");}}//猫类class Cat extends Animal{public void sleep(){System.out.println(super.name+ " 正在睡觉");}}
四.继承中有重复怎么办?
观察如下代码,我们可以看到在父类中有变量a,而子类中也定义了a。我们在
class Base{public int a = 10;public int b = 3;}class Derived extends Base{public int a = 20;public int c = 30;public void menthod(){System.out.println(a);}}public class menthod {public static void main(String[] args) {Derived derived = new Derived();System.out.println(derived.a);}}
1.访问原则
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。
1.如果访问的成员变量子类中有,优先访问自己的成员变量。
2.如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
3.如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
可以不可以打印出父类a的值? 这时就引出来我们的super和this
五.super和this
1.this
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
2.super
该关键字主要作用:在子类方法中访问父类的成员。
以上面的代码为例,可以得到这样的一个图解:
3.super注意事项
1.super不能出现在static修饰的方法。
2.子类在继承父类之后,要使用构造方法将父类成员进行初始化。
3.在子类构造方法中,会默认调用父类的无参构造方法,这是编译器自动添加的。默认是super()。
4.如果父类的构造方法是有参数的,则子类也需要是有参数的
在调用父类时,要先将父类的成员变量初始化
4.super和this异同点
相同点
1:都是关键字。
2:都不能出现在静态构造方法中
3:this()和super()都需要位于构造方法中的第一行,也就意味着this()和super()不能同时出现
不同点
1:this是对当前对象的引用;
2:this符合就近原则访问成员变量,super访问父类成员变量。
3:this()用来调用子类构造方法,super()调用父类构造方法;
4:若存在继承,在子类的构造方法中,一定有super(),若自己不自定义,编译器也会也会自动添加,而this()则没有。
六.构造方法的引入
1.父类不带参数的构造方法
在子类构造方法中,会默认调用父类的无参构造方法,这是编译器自动添加的。默认是super();
我们在实例化对象后,该怎么写就怎么写
public class Main {public static void main(String[] args) {Dog dog = new Dog();dog.name = "小黄";dog.age = 1;}}
2.父类带有参数的构造方法
这种情况就比较复杂了。蓝色背景的代码为新加入的构造方法。
观察代码,父类中自己定义了带参数的构造方法,这时我们在定义子类时,一定要先对父类的构造方法进行处理,这种处理通常是在自己的构造方法中默默使用super对父类构造方法进行涵盖,如下:
这里我们发现,在父类中使用this,在子类中使用super,这就跟上面解释的this和super的原理有关。
定义好之后,我们该如何使用呢?代码如下
public class Main {public static void main(String[] args) {Dog dog = new Dog("小黄",1);Cat cat = new Cat("喵喵",2);dog.eat();cat.sleep();}}
运行效果如下:
七.继承中的执行顺序
先说结论
1.父类的实例,
2.父类的构造,
3.子类的实例
4.子类的构造。
class Person{public String name;public int age;public Person(String name,int age){this.name = name;this.age = age;System.out.println("构造方法执行");}{System.out.println("实例化代码块执行");}static {System.out.println("静态代码块执行");}}class Student extends Person{public Student(String name,int age) {super(name,age);System.out.println("Student:构造方法执行");}{System.out.println("Student:实例代码块执行");}static {System.out.println("Student:静态代码块执行");}}public class testdemo {public static void main(String[] args) {Student student1 = new Student("张三",19);System.out.println("===========================");Student student2 = new Student("gaobo",20);}}
通过分析执行结果,得出以下结论:
1、父类静态代码块优先于子类静态代码块执行,且是最早执行
2、父类实例代码块和父类构造方法紧接着执行
3、子类的实例代码块和子类构造方法紧接着再执行
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行
八.继承方式
单继承
多层继承
不同类继承同一类
但是不支持多继承
时刻牢记, 我们写的类是现实事物的抽象. 而我们真正在公司中所遇到的项目往往业务比较复杂, 可能会涉及到一系列复杂的概念, 都需要我们使用代码来表示, 所以我们真实项目中所写的类也会有很多. 类之间的关系也会
更加复杂.
但是即使如此, 我们并不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了
如果想从语法上进行限制继承, 就可以使用 final 关键字
九.final
1:修饰变量,则该变量的值不能再被改变。
2:修饰类,则表示该类不能被继承
3:修饰方法,则该方法不能被重写
十.组合
和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法
(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段。
通俗来说就是继承反转过来。
轮胎类class Tire{// ...}// 发动机类class Engine{// ...}// 车载系统类class VehicleSystem{// ...}class Car{private Tire tire; // 可以复用轮胎中的属性和方法private Engine engine; // 可以复用发动机中的属性和方法private VehicleSystem vs; // 可以复用车载系统中的属性和方法// ...}
码字不易,感谢观看
如果对你有帮助的话,记得点赞评论+关注吧