java回顾之继承和抽象类
一、继承
1.1什么是继承
在java中需要写类来创建对象,类中需要些代码来给对象赋予一些功能。
假如现在我需要创建如下三个对象
对象: 功能
学生: 吃饭、睡觉、打游戏
老师:吃饭、睡觉、打学生
家长:吃饭、睡觉、打孩子
孩子:?????
假如没有继承,我们在写学生的时候需要写一下吃饭、睡觉的代码,写老师的时候需要写一下吃饭、睡觉的代码,写家长的时候需要写一下吃饭、睡觉的代码。
这样的话,其实吃饭、睡觉的代码是一样的,即使我们可以复制粘贴,这是三个类,如果让写一千个类呢?
所以我们可以给这三个类写一个共同的父类---中国人类,将吃饭、睡觉的代码写到中国人类当中,学生只写打游戏的方法、老师只写打学生的方法、家长只写打孩子的方法,吃饭睡觉不需要写,只要继承了,创建出来得 对象就具备这两样功能。
这样就解决了代码冗余,如果觉得这也没什么,那就想象下一千个类当中有几十个方法是相同的这种情况,继承的优越性就体现出来了
- 所以继承就是类和类之间的一种关系,子类可以继承父类中已经定义好的成员。
- extends表示继承
1.2继承图解
1.3继承的格式和好处
B类继承了A类:
public class B extends A{
}
好处:提高了代码的复用性、继承是多态的前提
代码演示
//人类
public class Person {
//姓名
String name;
//年龄
int age;
//吃饭
public void eat(){
System.out.println("一天三顿饭 一顿是半天");
}
//睡觉
public void sleep(){
System.out.println("一天睡两觉 一觉睡半天");
}
}
//学生类
public class Student extends Person{
//虽然在子类中没有定义姓名 年龄 吃饭 睡觉
//但是在父类中定义了子类就自动拥有的父类成员
}
//测试类
public class Demo继承的测试 {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
//可以赋值 学生类当中什么都没写,如果没有继承,是赋不了值的
s.name = "石原里美";
s.age =18;
//方法
s.eat();
s.sleep();
}
}
1.4 继承的内存图
二、方法重写
之所以有方法重写 是为了解决继承所产生的一些问题,比如继承的父类当中有个方法无法满足子类的需求,这个时候,只要在子类当中将方法重新写一遍,给此方法赋予新的功能,这就是方法的重写
方法重写的注解:
- @Override
这是一个注解,他的作用是检查这个方法是一个重写方法,如果这个方法不是重写方法就会报错
方法重写的规则:(听一下就好)
- 方法名:必须完全相同。
- 参数:参数类型和个数必须完全相同。
- 权限修饰符:子类的权限修饰符必须大于等于父类的权限修饰符
- 返回值类型:子类的返回值类型必须小于等于父类的返回值类型
(小于的意思是说子类的返回值类型可以是父类返回值类型的子类) - 结论:对于这个规则,不用强求背他,绝大多数的情况都是完全相同的。也就是说权限修饰符和返回值类型特殊情况不多见。
2.2 设么内容不能被子类继承或访问
private修饰的成员子类可以继承,但是不能使用
构造方法是不能被继承的。这里要注意,每个类被创建的时候,系统都会自动调用空参构造,所以说空参构造是每个类都有的,所以构造方法不会被继承。
另外如果写了有参构造的话,类默认的无参构造就会失效,这个时候又有类继承了这个类,由于父类只有有参没有无参,这个时候就会报错,这是因为java中如果创建一个类的话,这个类会回溯到object,默认的无参构造方法就是回溯的路径,所以当中间某一段,只有有参没有无参,路径就断了,所以在java中我们写一个类时,会将有参构造和无参构造都写出来,防止报错。
总结:
1. 构造器的名字是与类名一致的。所以子类是无法继承父类构造方法的。
2. 构造器的作用是初始化对象成员变量数据的。所以子类的初始化过程中,必须先执行父类的初始化
动作。子类的构造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化
后,才可以给子类使用。(先有爸爸,才能有儿子)
继承后子类构造器特点:子类所有构造器的第一行都会先调用父类的无参构造器,再执行自己
2.3this和super关键字
this代表成员变量、super代表父类成员
要注意:
this():表示调用本类的构造方法
super():表示调用父类的构造方法
在构造方法中this()和super()只能出现一个,且必须放在方法的第一行
在写代码的时候,只需要使用idea生成构造方法就可以了。
2.4 继承的注意事项
java继承中一个子类只能继承一个父类(只能有一个亲爹)
java继承中可以多重继承,可以有父类,可以有爷爷类(家族体系)
java继承中只有属于关系才可以继承,这不是java代码规范,这是开发规范,要跟实际生活联系在一起,你不能让一个猫的类去继承汽车类,这是属于瞎继承,虽然代码不会报错,但是在开发中就是有毛病了。
三、抽象类
3.1 什么是抽象类
父类中的方法,被它的子类们重写 ,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有方法声明才有意义(方法的名字),方法的主体则没有意义(因为要实现的功能不一样),换句话说,父类可能知道子类应该有哪个功能,但是功能具体怎么实现父类是不清楚的(有子类自己决定),父类完全只需要 提供一个没有方法体的方法签名即可,具体实现给子类自己去实现。
我们把没有方法体的方法称为抽象方法。java语法规定,包含抽象方法的类就是抽象类,因为不是抽象类也包含不了抽象方法
抽象类格式
public abstract class 类名{
}
抽象方法格式
//抽象方法没有方法体
public abstract 返回值类型 方法名(参数类型 参数名);
public abstract void eat();
抽象方法可以要求子类必须重写某个方法,以此来完成某个功能