第一节:Java继承之继承概念语法成员访问和super关键字

Posted 快乐江湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第一节:Java继承之继承概念语法成员访问和super关键字相关的知识,希望对你有一定的参考价值。

文章目录

一:继承的概念及语法

(1)什么是继承

继承:是指能够直接获得已有的性质和特征,而不必重复定义它们。在面向对象的软件技术中,继承是子类自动地共享父类中定义的数据和方法的机制。子类继承父类后,即实现了代码的复用,又使子类可以在父类的基础上进行扩展

例如下面有两个类,分别是DogCat,用于描述自然界中的狗和猫

class Dog
    public String name;
    public int age;
    public float weight;

    public void eat()
        System.out.println(name + "正在吃饭");
    
    public void bark()
        System.out.println(name + "正在吠叫");
    


//猫
class Cat
    public String name;
    public int age;
    public float weight;

    public void eat() 
        System.out.println(name + "正在吃饭");
    

    public void meow()
        System.out.println(name + "正在喵喵");

    

从代码中可以看到,狗和猫之间存在一些共性

  • 共同的属性nameageweight
  • 共同的行为eat()

所以,继承的作用就体现出来了,也即抽取共性。狗和猫本质都是动物,所以我们可以把它们共同的属性和方法给抽取出来,形成一个新的类Animal,此时DogCat之间就存在了父子类关系

  • 父类(基类)Animal
  • 子类(派生类)DogCat

(2)Java继承语法

继承语法:在Java中如果要表示类之间的继承关系,需要借助extends关键字,格式如下

修饰符 class 子类 extends 父类
	....

接着,对(1)中所述情况用代码设计如下

class Animal
    public String name;
    public int age;
    public double weight;

    public void eat()
        System.out.println(name + "正在吃饭");
    


//狗
class Dog extends Animal

    public void bark()
        System.out.println(name + "正在吠叫");
    


//猫
class Cat extends Animal
    public void meow()
        System.out.println(name + "正在喵喵");

    




public class TestDemo 
    public static void main(String[] args) 
        Dog dog = new Dog();
        dog.name = "狗蛋";
        dog.age = 5;
        dog.weight = 34.3;
        Cat cat = new Cat();
        cat.name = "花喵";
        cat.age = 4;
        cat.weight = 21.2;

        System.out.println(dog.name);
        dog.eat();
        dog.bark();

        System.out.println(cat.name);
        cat.eat();
        cat.meow();
    

二:成员访问

(1)子类访问父类的成员变量

子类和父类不存在同名成员变量:这种情况容易理解,没什么问题

class Base
    public int a = 1;
    public int b = 2;


class Sub extends Base
    public int c = 3;


public class TestDemo2 
    public static void main(String[] args) 
        Sub sub = new Sub();
        System.out.println("sub_a form Base:" + sub.a);
        System.out.println("sub_b form Base:" + sub.b);
        System.out.println("sub_c:" + sub.c);
    

子类和父类存在同名成员变量:访问时遵循就近原则,自己有就访问自己的,没有则会在父类中找寻

class Base
    public int a = 1;
    public int b = 2;
    public int c = 3;


class Sub extends Base
    public int a = 11;  //与父类中的a同名且类型相同
    public String b = "Hello";  //与父类中成员b同名,但类型不同



public class TestDemo2 
    public static void main(String[] args) 
        Sub sub = new Sub();
        System.out.println(sub.a);//访问子类中的a
        System.out.println(sub.b);//访问子类中的b
        System.out.println(sub.c);//访问父类中的c
    

(2)子类访问父类的成员方法

子类和父类不存在同名成员变量:这种情况容易理解,没什么问题

class Base
    public void base_method()
        System.out.println("父类中的方法");
    


class Sub extends Base
    public void sub_method()
        System.out.println("子类中的方法");
    


public class TestDemo2 
    public static void main(String[] args) 
        Sub sub = new Sub();
        sub.base_method();//从父类继承的方法
        sub.sub_method();//子类自己的方法
    

子类和父类存在同名成员变量:遵循就近原则,子类有就访问子类的,没有就用父类的。同时如果父类和子类同名方法构成重载,那么它就会根据调用方法所传递的参数选择合适的方法调用

class Base
    public void method1()
        System.out.println("父类中的方法1");
    
    public void method2()
        System.out.println("父类中的方法2");
    


class Sub extends Base
    //该方法与父类同名方法构成重载
    public void method1(int a)
        System.out.println("子类中的方法1");
    
    public void method2()
        System.out.println("子类中的方法2");
    


public class TestDemo2 
    public static void main(String[] args) 
        Sub sub = new Sub();
        sub.method1();//没有传参,访问父类方法
        sub.method1(10);//传参,访问子类方法
        sub.method2();//子类有,则直接访问子类的
    

三:super关键字

(1)super关键字

A:作用一:访问父类同名成员

从前文可以看到,子类是不能够直接访问父类的同名成员的。而在Java中,可以使用super关键字解决

  • 注意: 仅仅可以在非静态方法中使用
class Base
    int a;
    int b;
    public void method1()
        System.out.println("父类中的方法1");
    
    public void method2()
        System.out.println("父类中的方法2");
    


class Sub extends Base
    int a;//与父类中的变量a同名且类型相同
    String b;//与父类中的变量b同名但类型不同

    //该方法与父类中的同名方法构成重载
    public void method1(int a)
        System.out.println("子类中的方法1");
    
    //该方法与父类中的同名方法构成重写
    public void method2()
        System.out.println("子类中的方法2");
    

    public void test()
        //同名成员变量直接访问时,都是子类的
        a = 100;
        b = "Hello";

        //访问父类成员变量是需要借助super关键字
        super.a = 300;
        super.b = 400;

        //对于父类和子类中构成重载的方法,通过参数就可以区别他们
        method1();//父类的
        method1(10);//子类的

        //如果要访问被重写的父类方法,则需要借助super关键字
        method2();//由于被重写,所以访问的永远是子类的
        super.method2();//父类的
    



public class TestDemo2 
    public static void main(String[] args) 
        Sub sub = new Sub();
        sub.test();
    

B:作用二:调用父类构造方法

有如下代码,子类Sub1Sub2中的变量a和b继承自父类Base,同时它们各自拥有自己的变量c。当给父类Base加入构造函数后却发现编译器报错

这是因为:构造子类对象时,先会执行父类的构造方法,然后再执行子类的构造方法。所以对于子类对象,它必须先调用父类的构造方法,这正是super关键字的第二个作用

class Base
    int a;
    int b;
    public Base(int a, int b)
        this.a = a;
        this.b = b;
    


class Sub1 extends Base
    int c;
    public Sub1(int a, int b, int c)
        super(a, b);
        this.c = c;
    


class Sub2 extends Base
    int c;
    public Sub2(int a, int b, int c)
        super(a, b);
        this.c = c;
    


public class TestDemo2 
    public static void main(String[] args) 
        Sub1 sub1 = new Sub1(1, 2, 3);
        Sub1 sub2 = new Sub1(4, 5, 3);
        System.out.println(sub1.a);
        System.out.println(sub1.b);
        System.out.println(sub1.c);
        System.out.println(sub2.a);
        System.out.println(sub2.b);
        System.out.println(sub2.c);
    

需要注意:

  • 如果父类使用的是默认构造方法或显示定义了无参的构造方法,那么子类构造方法第一行会默认隐含super调用
  • super只能在子类构造方法第一行出现,且只能出现一次,并且不可以和this同时出现

(2)super和this对比

相同点

  • 都可以在成员方法(仅限于非静态方法)中用来访问成员变量或调用其他成员方法(非静态)
  • 都可以作为构造方法的第一条语句(必须是),并且不能同时存在

不同点

  • this当前对象的引用,用来访问本类的成员super是子类从父类中继承下来的部分成员的引用,用来访问从父类的成员
  • this是非静态成员方法的一个隐藏参数super不是隐藏参数
  • 在构造方法中,this()用于调用本类构造方法;super()用于调用父类构造方法。二者不能在构造方法中不能同时出现
  • 构造方法中一定会存在super()调用,但this()如果用户不写则不会默认存在

以上是关于第一节:Java继承之继承概念语法成员访问和super关键字的主要内容,如果未能解决你的问题,请参考以下文章

JAVA面对对象三大特征之继承多态

Java继承与组合

C++之继承详解

深入浅出之C++中的继承

Java之继承

java——继承封装多态概念和例子