栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java面向对象编程之继承(包括super关键字详解)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java面向对象编程之继承(包括super关键字详解)

初识继承

继承的概念有点抽象,让我们先看看下面这个例子

package inherit;

public class Animal {
    String name;

    public Animal(String name) {
        this.name = name;
    }

    public void eat(String food){
        System.out.println(this.name+"正在吃"+food);
    }
}

class Cat{
    String name;

    public Cat(String name) {
        this.name = name;
    }

    public void eat(String food){
        System.out.println(this.name+"正在吃"+food);
    }
    public void grab(){
        System.out.println(this.name+"捉老鼠");
    }
}

class Bird{
    String name;

    public Bird(String name) {
        this.name = name;
    }

    public void eat(String food){
        System.out.println(this.name+"正在吃"+food);
    }
    public void fly(){
        System.out.println(this.name+"正在飞");
    }


}

可以看出上面的代码存在许多重复的部分,按道理说所有Animal的类都应该具备name属性以及eat这个方法。

那么有没有一种方法可以使bird,cat可以使用animal中的name属性以及eat这个方法呢?

继承就可以实现这种功能

继承就是在已经存在类的基础上进行扩展,从而产生新的类。已经存在的类称为父类、基类或超类,而新产生的类称为子类或派生类。

比如,Cat is an Animal,Bird is An Animal,当类和类之间满足一个类is a 另一个类时,一定存在继承关系。此时我们就可以让 Cat 和 Bird 分别继承 Animal 类, 来达到代码重用的效果.

通过继承我们可以将上面的代码进行缩减

package inherit;


class Animal {
    String name;

    public Animal() {
    }

    public Animal(String name) {
        this.name = name;
    }

    public void eat(String food){
        System.out.println(this.name+"正在吃"+food);
    }
}

class Cat extends Animal{


    public Cat(String name) {
        this.name = name;
    }

    public void grab(){
        System.out.println(this.name+"捉老鼠");
    }
}

class Bird extends Animal{


    public Bird(String name) {
        this.name = name;
    }

    public void fly(){
        System.out.println(this.name+"正在飞");
    }


}
public class Test {
    public static void main(String[] args) {
        Cat cat=new Cat("猫猫");
        Bird bird=new Bird("小鸟");
        cat.eat("鱼");
        bird.eat("虫");
    }
}

继承的规则
  • 继承用extends关键字表示:class 子类 extends 父类
  • 一个子类只能继承一个父类(单继承),java中不允许多继承,extands后面只能跟一个父类,允许多层继承
  • 子类会继承父类的所有属性和方法,有显示继承(public 属性和方法可以直接使用),也有隐式继承(private属性和方法),其实子类也继承了这个属性和方法,但是无法直接使用

明白了继承的规则之后,让我们来思考一个问题,若此时子类和父类中存在同名属性或方法时,访问的到底是子类还是父类呢?

让我们看看下面这段代码

package inherit;


class Base {  // 父类
    int a = 5;
    int b = 100;
    public void method() {
        System.out.println("这是父类的普通方法");
    }
}
class Derived extends Base {  // 子类通过extends关键字继承父类
    int a = 10;
    int c = 1000;
    public void test () {
        System.out.println("当调用子类和父类同名的成员变量a时,打印的是:" + this.a);
        System.out.println("当调用只有子类中有的成员变量c时,打印的是:" + this.c);
        System.out.println("当调用只有父类中有的成员变量b时,打印的是:" + this.b);
    }
}
public class Test3 {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.test();
    }
}

由此可见当子类与父类属性与方法重名的时候,优先访问子类的属性和方法,当子类中没有这个属性时才会访问父类的

super关键字的使用

看了上面的代码之后,相信你可能会有这样的疑问,当子类与父类属性和方法重名时,若我想访问父类的属性和方法该怎么办?

此时,super关键字就派上用场了

package inherit;


class Base {  // 父类
    int a = 5;
    int b = 100;
    public void method() {
        System.out.println("这是父类的普通方法");
    }
}
class Derived extends Base {  // 子类通过extends关键字继承父类
    int a = 10;
    int c = 1000;
    public void test () {
        System.out.println("当调用子类和父类同名的成员变量a时,默认打印的是:" + this.a);
        System.out.println("当调用子类和父类同名的成员变量a时,使用super关键字打印的是:" + super.a);
    }
}
public class Test3 {
    public static void main(String[] args) {
        Derived derived = new Derived();
        derived.test();
    }
}

注意:

当有继承关系时this关键字默认再当前类中寻找同名属性,若没找到,继续向上寻找父类中是否有同名属性

super关键字修饰属性

表示从父类中寻找同名属性,上面的代码就展示了这个过程。

若直接父类不存在同名属性再向上寻找

class A{
    int a=6;
}
class B extends A{
    int b=1;
}
class C extends B{
    int a=5;
    public void test(){
        System.out.println(super.a);
    }
}
public class Test2 {
    public static void main(String[] args) {
        C c=new C();
        c.test();

    }
}
//输出6
super关键字修饰方法
  • 修饰构造方法
package inherit;

class Person{
    String name;
    int age;

    public Person() {
        System.out.println("Person的无参构造");
    }
}

class Chinese extends Person{
    public Chinese() {
        //编译器会自动在子类构造函数的第一句加上 super(); 来调用父类的无参构造器
        //此时可以省略不写。如果想写上的话必须在子类构造函数的第一句
        System.out.println("Chinese的无参构造");
    }

}
public class Test4 {
    public static void main(String[] args) {
        Chinese chinese=new Chinese();
    }
}

注意:当我们要产生一个子类对象时,默认先产生一个父类对象,即调用子类构造方法前默认先调用父类构造方法,通过在子类构造方法的第一行写上super(参数)

package inherit;

class Person{
    String name;
    int age;

   public Person(String name) {
        this.name = name;
        System.out.println("Person的一个有参构造,name是:"+name);
    }
}

class Chinese extends Person{
    public Chinese(String name) {
        super(name);//父类没有无参构造,必须在子类构造方法的第一行,显示地写上super(参数)
        System.out.println("Chinese的有参构造");
    }

}
public class Test4 {
    public static void main(String[] args) {
        Chinese chinese=new Chinese("小明");
    }
}

注意:若父类不存在无参构造则,子类构造方法的首行必须使用super(有参构造)

  • 修饰普通方法

与修饰属性类似,直接从父类中寻找同名方法

package inherit;

class Person{
    String name;
    int age;

//    public Person() {
//        System.out.println("Person的无参构造");
//    }

    public Person(String name) {
        this.name = name;
        System.out.println("Person的一个有参构造,name是:"+name);
    }
    public void fun(){
        System.out.println("Person的一个普通方法");
    }
}
class Chinese extends Person{

//    public Chinese() {
//        //编译器会自动在子类构造函数的第一句加上 super(); 来调用父类的无参构造器
//        //此时可以省略不写。如果想写上的话必须在子类构造函数的第一句,
//        System.out.println("Chinese的无参构造");
//    }


    public Chinese(String name) {
        super(name);
        System.out.println("Chinese的有参构造");
    }

    public void test(){
        super.fun();//调用父类的普通方法
    }
}
public class Test4 {
    public static void main(String[] args) {
        Chinese chinese=new Chinese("小明");
        chinese.test();
    }
}

注意:

与this不同,super不能指代当前父类的对象引用,此时编译器报错

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/854973.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号