java 学习(九)之继承

java 学习(九)之继承

继承

在前一课中,您已经多次提到继承。在 Java 语言中,类可以从其他类中提取,从而从这些类中继承字段和方法。


**定义:**源自其他类的类称为子类(也是子类扩展类儿童类)。子类的衍生类称为超级类(也是基础类父类)。
除了没有超级类,每个类只有一个直接超级类(单个继承
)。在没有任何其他明确的超级类,每个类是含蓄的子类。
类可以从类中衍生出,从类中衍生,等等,最终从最顶级的类中衍生
出来。据说,这样的阶级是继承链中所有阶级的后裔Object``Object``Object``Object


继承的想法很简单,但很强大:当你想要创建一个新的类,并且已经有一个类,其中包括一些你想要的代码,你可以从现有的类中获取您的新类。在此过程中,您可以重复使用现有类的字段和方法,而无需自己编写(调试!

子类从其超级类中继承所有成员(字段、方法和嵌套类)。构造器不是成员,因此它们不是子类遗传的,但可以从子类中调用超级类的构造器。

语法:Java 中的继承

要继承一个类,我们使用extends关键字。这里的类XYZ是子类,类ABC是父类。XYZ类继承了ABC类的属性和方法。

class XYZ extends ABC
{
    
    
    //TODO something
}

让我们来复习下pythonc#的继承

class XYZ:ABC:
        # TODO something
class XYZ:ABC{
    //TODO something
}  

继承示例


在这个例子中,我们有一个基类Teacher和一个子类PhysicsTeacher。由于类PhysicsTeacher扩展了基类的designationcollegeName属性以及does()方法,我们不需要在子类中声明这些属性和方法。

这里我们有collegeNamedesignationdoes()方法,这些方法对于所有老师都是通用的,所以我们在基类中声明了它们,这样像MathTeacherMusicTeacherPhysicsTeacher这样的子类不会需要编写此代码,可以直接从基类中使用。

class Teacher {
    
    
   String designation = "Teacher";
   String collegeName = "Beginnersbook";
   void does(){
    
    
    System.out.println("Teaching");
   }
}

public class PhysicsTeacher extends Teacher{
    
    
   String mainSubject = "Physics";
   public static void main(String args[]){
    
    
    PhysicsTeacher obj = new PhysicsTeacher();
    System.out.println(obj.collegeName);
    System.out.println(obj.designation);
    System.out.println(obj.mainSubject);
    obj.does();
   }
}

输出:

Beginnersbook
Teacher
Physics
Teaching

基于上述例子,我们可以说PhysicsTeacher IS-A Teacher。这意味着子类与父类具有 IS-A 关系。这是继承被称为子类和父类之间的 IS-A 关系

注意:

派生类继承声明为publicprotected的所有成员和方法。如果超类的成员或方法声明为private,则派生类不能直接使用它们。私有成员只能在自己的类中访问。只能使用公共或受保护的超类获取器和设置器方法访问此类私有成员,如下例所示。

class Teacher {
    
    
   private String designation = "Teacher";
   private String collegeName = "Beginnersbook";
   public String getDesignation() {
    
    
    return designation;
   }
   protected void setDesignation(String designation) {
    
    
    this.designation = designation;
   }
   protected String getCollegeName() {
    
    
    return collegeName;
   }
   protected void setCollegeName(String collegeName) {
    
    
    this.collegeName = collegeName;
   }
   void does(){
    
    
    System.out.println("Teaching");
   }
}

public class JavaExample extends Teacher{
    
    
   String mainSubject = "Physics";
   public static void main(String args[]){
    
    
    JavaExample obj = new JavaExample();
    /* Note: we are not accessing the data members 
     * directly we are using public getter method 
     * to access the private members of parent class
     */
    System.out.println(obj.getCollegeName());
    System.out.println(obj.getDesignation());
    System.out.println(obj.mainSubject);
    obj.does();
   }
}

输出是:

Beginnersbook
Teacher
Physics
Teaching

在上面的例子中需要注意的重要一点是,子类能够通过父类的受保护方法访问父类的私有成员。当我们创建一个实例变量(数据成员)或方法受保护时,这意味着它们只能在类本身和子类中访问。这些公共,受保护,私有等都是访问说明符,我们将在接下来的教程中讨论它们。

继承的类型


单一继承:指的是一个子类和父类关系,其中一个类扩展另一个类。

Java 类单一继承

多级继承:指一个类扩展子类的子类和父类关系。例如,C类扩展了B类,B类扩展了A类。

Java 类多级继承

分层继承:指的是子类和父类关系,其中多个类扩展同一个类。例如,BCB类。D扩展了相同的A类。

Java 类分层继承

多重继承 :指一个类扩展多个类的概念,这意味着子类有两个父类。例如,类C扩展了类AB. Java 不支持多重继承。

Java类多重继承

混合继承:在单个程序中组合多种类型的继承。例如A类和A类。B扩展了类C,另一个类D扩展了类A,然后这是一个混合继承示例,因为它是单继承和层次继承的组合。

构造函数和继承


当我们创建子类的对象时,会调用子类的构造函数,它默认调用超类的默认构造函数。因此,在继承中,对象是自上而下构造的。可以使用super关键字显式调用超类构造函数,但它应该是构造函数中的第一个语句。super关键字指的是超类,紧接在层次结构中的调用类之上。不允许使用多个super关键字来访问除直接父级之外的祖先类。

class ParentClass{
    
    
   //Parent class constructor
   ParentClass(){
    
    
    System.out.println("Constructor of Parent");
   }
}
class JavaExample extends ParentClass{
    
    
   JavaExample(){
    
    
    System.out.println("Constructor of Child");
   }
   public static void main(String args[]){
    
    
    //Creating the object of child class
    new JavaExample();
   }
}

输出:

Constructor of Parent
Constructor of Child

继承和方法覆盖


当我们在父类中已经存在的子类中声明相同的方法时,这称为方法覆盖。在这种情况下,当我们从子类对象调用该方法时,将调用该方法的子类版本。但是我们可以使用super关键字调用父类方法,如下例所示:

class ParentClass{
    
    
   //Parent class constructor
   ParentClass(){
    
    
    System.out.println("Constructor of Parent");
   }
   void disp(){
    
    
    System.out.println("Parent Method");
   }
}
class JavaExample extends ParentClass{
    
    
   JavaExample(){
    
    
    System.out.println("Constructor of Child");
   }
   void disp(){
    
    
    System.out.println("Child Method");
        //Calling the disp() method of parent class
    super.disp();
   }
   public static void main(String args[]){
    
    
    //Creating the object of child class
    JavaExample obj = new JavaExample();
    obj.disp();
   }
}

输出是:

Constructor of Parent
Constructor of Child
Child Method
Parent Method
main(String args[]){
    
    
    //Creating the object of child class
    JavaExample obj = new JavaExample();
    obj.disp();
   }
}

输出是:

Constructor of Parent
Constructor of Child
Child Method
Parent Method

java子类继承父类执行顺序

java new一个类对象,类中各部分执行顺序:

静态代码块—非静态代码块—构造函数—一般方法。

public class father {
    
    
    
    private String name;

    father(){
    
    
       System.out.println("--父类的无参构造函数--");
    }

    father(String name){
    
    
       this.name=name;
       System.out.println("--父类的有参构造函数--"+this.name);
    }

    static{
    
    
       System.out.println("--父类的静态代码块--");
    }

    {
    
    
       System.out.println("--父类的非静态代码块--");
    }

    public void speak(){
    
    
       System.out.println("--父类的方法--");
    }

    public static void main(String[] args) {
    
    
        System.out.println("--父类主程序--");
        father father=new father("父亲的名字");
        father.speak();
     }
    
}

运行如上main方法结果为:

在这里插入图片描述
创建子类继承该父类测试执行顺序

public class Son extends father{
    
    
     private String name;

        static{
    
    
           System.out.println("--子类的静态代码块--");
        }

        {
    
    
           System.out.println("--子类的非静态代码块--");
        }

        Son(){
    
    
           System.out.println("--子类的无参构造函数--");
        }

        Son(String name){
    
    
           this.name=name;
           System.out.println("--子类的有参构造函数--"+this.name);
        }

        @Override
        public void speak(){
    
    
           System.out.println("--子类Override了父类的方法--");
        }

        public static void main(String[] args) {
    
    
               System.out.println("--子类主程序--");

               Son son=new Son("儿子的名字");
               son.speak();
        }
}

运行如上main方法结果如下:
在这里插入图片描述
运行如下main方法:

public static void main(String[] args) {
    
    
               System.out.println("--子类主程序--");

               Son son=new Son("儿子的名字");
               son.speak();

               father father=new father("父亲的名字");
               father.speak();

        }

在这里插入图片描述
子类继承父类各部分执行顺序为:父静态代码块–子静态代码块–父非静态代码–父无参构造函数–子静态代码块–子构造函数–方法。

猜你喜欢

转载自blog.csdn.net/qq_45205390/article/details/120874355