java回顾之继承和抽象类

一、继承

1.1什么是继承

  在java中需要写类来创建对象,类中需要些代码来给对象赋予一些功能。

  假如现在我需要创建如下三个对象

  对象:                功能

  学生: 吃饭、睡觉、打游戏

  老师:吃饭、睡觉、打学生

  家长:吃饭、睡觉、打孩子

       孩子:?????

  假如没有继承,我们在写学生的时候需要写一下吃饭、睡觉的代码,写老师的时候需要写一下吃饭、睡觉的代码,写家长的时候需要写一下吃饭、睡觉的代码。

  这样的话,其实吃饭、睡觉的代码是一样的,即使我们可以复制粘贴,这是三个类,如果让写一千个类呢?

  所以我们可以给这三个类写一个共同的父类---中国人类,将吃饭、睡觉的代码写到中国人类当中,学生只写打游戏的方法、老师只写打学生的方法、家长只写打孩子的方法,吃饭睡觉不需要写,只要继承了,创建出来得 对象就具备这两样功能。

  这样就解决了代码冗余,如果觉得这也没什么,那就想象下一千个类当中有几十个方法是相同的这种情况,继承的优越性就体现出来了

  • 所以继承就是类和类之间的一种关系,子类可以继承父类中已经定义好的成员。
  • extends表示继承

1.2继承图解

java方法的重写的父类可以在调用吗 java中重写父类抽象方法_父类

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 继承的内存图

java方法的重写的父类可以在调用吗 java中重写父类抽象方法_java方法的重写的父类可以在调用吗_02

 

 

 

二、方法重写

  之所以有方法重写 是为了解决继承所产生的一些问题,比如继承的父类当中有个方法无法满足子类的需求,这个时候,只要在子类当中将方法重新写一遍,给此方法赋予新的功能,这就是方法的重写

  

  方法重写的注解:

  • @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();

  抽象方法可以要求子类必须重写某个方法,以此来完成某个功能