继承

现在我们要写一个狗类,也要写一个猫类:

package oop1;

public class Dog {

    public String name;
    public int age;
    public String color;

    public void eat(){
        System.out.println("吃饭");
    }

    public void sleep(){
        System.out.println("睡觉");
    }
}

package oop1;

public class Cat {

    public String name;
    public int age;
    public String color;

    public void eat(){
        System.out.println("吃饭");
    }

    public void sleep(){
        System.out.println("睡觉");
    }
}

可以发现,猫类和狗类中属性和方法是一样的,看下来代码几乎是一样的,但是我们还得写两遍,这就很麻烦,虽然可以复制粘贴,但是当后续又有猪、猴、马、兔呢?所以我们想要类似于一个模板一样的东西。在Java中我们可以使用继承。

1.什么是继承?

Java中将多个类中具有的相同属性和方法抽取出来,写到一个单独的类中,将这个类作为父类,这里就涉及到了继承的概念,其它的类使用这个类去生成新的类,就叫继承了这个类,这个类就是父类,继承父类的其它类就作为该父类的子类

父类也叫基类、超类。子类也可叫做派生类。

我们将上述猫、狗类中的属性和方法抽取出来,放到一个Pet类中,Dog、Cat类继承Pet:

继承的关键字:extends

语法:子类 extends 父类

Pet:

package oop1;

public class Pet {

    public String name;
    public int age;
    public String color;

    public void eat(){
        System.out.println("吃饭");
    }

    public void sleep(){
        System.out.println("睡觉");
    }
}

Dog:继承Pet类

public class Dog extends Pet{

}

Cat:继承Pet类

public class Cat extends Pet{

}

如果我们再多几个动物类,也可以继承Pet类,这样是不是就减少了很多的代码量呢?继承的好处就是:代码重用

2.继承的使用

(1)子类拥有了父类的哪些东西?

那继承了父类有什么用呢?我们就可以使用父类的属性和方法了。

我们在Dog类中new一个对象,使用.来查看一下有没有什么:

继承

我们可以看到,Dog类的对象拥有了父类的全部属性和方法。

package oop1;

public class Dog extends Pet{

    public static void main(String[] args) {
        //使用父类属性
        Dog dog = new Dog();
        dog.name = "哈士奇";
        dog.age = 3;
        dog.color = "黑";
        System.out.println(dog.name+"\t"+dog.age+"\t"+dog.color);
        //调用父类方法
        dog.eat();
        dog.sleep();
    }
}

运行也是没有问题的:

继承

这就像儿子可以使用父亲的很多东西一样,但是儿子可以使用父亲的所有东西吗?这肯定是不可以的,那继承的东西是否也会有限制呢?我们再来看看四个权限修饰符的权限表:

继承

在学了父类、子类概念后,现在我们已经可以看明白整个表了。可以看到,private修饰的就算是同一个包下的子类都是不可访问的,我们来实验一下,将属性修改成四个不同权限修饰符修饰:

package oop1;

public class Pet {

    public String name;
    protected int age;
    String color;
    private double price;

    public void eat(){
        System.out.println("吃饭");
    }
    
    protected void walk(){
        System.out.println("散步");
    }
    
    void play(){
        System.out.println("玩耍");
    }

    private void sleep(){
        System.out.println("睡觉");
    }
}

继承

再验证一下不同包下的子类:

继承

验证结果与表中一致,所以得出结论:同一包下的子类,继承父类之后,就拥有了父类中除私有的属性和方法;不同包下的子类,继承父类之后,就拥有了除私有的和默认的以外的私有属性和方法。

(2)子类能否继承父类的构造方法?

我们说子类可以继承父类的符合权限的属性和方法,那我们知道构造方法是特殊的方法,父类的构造方法能否被子类继承呢?

构造方法是用来创建唯一的东西的,如果子类继承了父类的构造方法,则在创建对象时就不知道创建的是父对象还是子对象,调用父类的构造方法,不会创建一个父对象,只是初始化父类的成员属性和方法(因为子类继承父类后,会获取到父类的属性和方法,这些属性和方法在使用前必须先初始化,所以须先调用父类的构造器进行初始化)。

也不会产生父类对象,只是用了父类的构造方法而已,并不是用到构造方法就会产生对象,构造方法只是起对象初始化作用的,而不是起产生对象作用的;即只有 new 语句才会产生父类的对象。

所以,子类不会继承父类的构造方法,但是会调用父类的构造方法用于初始化。

package oop1;

public class Pet {

    public Pet() {
        System.out.println("我是父类的构造方法");
    }
}

package oop1;

public class Cat extends Pet{

    public Cat() {
        System.out.println("我是子类的构造方法");
    }

    public static void main(String[] args) {
        Cat cat = new Cat();
    }

}

继承

这里看到虽然输出了父类的构造方法中的输出语句,但是只是子类在new对象时调用了父类的构造方法而已。这是一个很容易混淆和绕晕自己的点。

扩展:

可以从结果中看出,在子类中new对象,是先输出了父类的构造方法中的内容,再输出了子类构造方法中的内容,这里涉及到了:

继承关系的初始化顺序:

父类的属性
父类的构造方法
子类的属性
子类的构造方法

(3)能否继承多个类?

既然继承那么好用,我们可不可以多继承几个类呢?

继承

是不可以的,提示中写着类不能继承多个类,所以Java是单继承,只能直接的继承一个类。

(4)继承了父类之后还能不能有自己的属性和方法?

子类继承了父类之后,还能不能定义自己的属性和方法呢?

Pet:父类

package oop1;

public class Pet {

    public String name;
    public int age;
    public String color;

    public void eat() {
        System.out.println("吃饭");
    }

    public void sleep() {
        System.out.println("睡觉");
    }
}

Cat:子类

package oop1;

public class Cat extends Pet{

    public double price;
    
    public void play(){
        System.out.println("猫抓老鼠");
    }

    public static void main(String[] args) {
        Cat cat = new Cat();
        //继承父类属性
        cat.name = "肥橘";
        //子类自定义属性
        cat.price = 1000;
        //继承父类方法
        cat.eat();
        //子类自定义方法
        cat.play();
    }
}

子类继承了父类具有权限的属性和方法之后,也可以自定义独有的属性和方法。


3.总结

  • 同一包下的子类,继承父类的除私有的以外的属性和方法;
  • 不同包下的子类,继承父类的除私有的和默认的以外的属性和方法;
  • 子类不继承父类的构造方法;
  • 单继承,只能直接继承一个类;
  • 继承父类之后,子类还能自定义属性和方法。

本人水平有限,若有错误,望指出~

上一篇:2021-01-18


下一篇:PC-Lint概念与基本操作