📜  Java继承

📅  最后修改于: 2020-09-26 14:46:17             🧑  作者: Mango

在本教程中,我们将借助示例学习Java中的继承。

继承是OOP(面向对象编程)的关键功能之一,它使我们能够从现有类中定义一个新类。例如,

class Animal
{
    // eat() method
    // sleep() method
}
class Dog extends Animal
{
    // bark() method
}

在Java中,我们使用extends关键字从类继承。在这里,我们从Animal类继承了Dog类。

动物是超类(父类或基类),而是子类(子类或派生类)。子类继承超类的字段和方法。

Java继承简介


是关系

继承是is-a的关系。仅在两个类之间存在is-a关系时才使用继承。

这里有些例子:

  • 汽车就是车辆。
  • 橙色是一种水果。
  • 外科医生是医生。
  • 狗是动物。

示例1:Java继承

class Animal {

   public void eat() {
      System.out.println("I can eat");
   }

   public void sleep() {
      System.out.println("I can sleep");
   }
}

class Dog extends Animal {
   public void bark() {
      System.out.println("I can bark");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();

      dog1.eat();
      dog1.sleep();

      dog1.bark();
   }
}

输出

I can eat
I can sleep
I can bark

在这里,我们从超类Animal继承了Dog的子类。 Dog类从Animal类继承了eat()sleep()方法。

因此, Dog类的对象可以访问Dog类和Animal类的成员。

在Java继承中,子类的对象可以调用超类的成员。


受保护的关键字

在先前的教程中,我们了解了privatepublic访问修饰符。

  • private成员只能在班级内访问
  • 可以从任何地方访问public成员

您还可以分配protected方法和字段。受保护的成员可以访问

  • 从班级内部
  • 在其子类中
  • 在同一包装内

这是可以访问访问修饰符的摘要。

  Class Package subclass World
public Yes Yes Yes Yes
private Yes No No No
protected Yes Yes Yes No

示例2:受保护的关键字

class Animal {
   protected String type;
   private String color;

   public void eat() {
      System.out.println("I can eat");
   }

   public void sleep() {
      System.out.println("I can sleep");
   }

   public String getColor(){
      return color;
   }

   public void setColor(String col){
      color = col;
   }
}

class Dog extends Animal {
   public void displayInfo(String c){
      System.out.println("I am a " + type);
      System.out.println("My color is " + c);
   }
   public void bark() {
      System.out.println("I can bark");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();
      dog1.eat();
      dog1.sleep();
      dog1.bark();
 
      dog1.type = "mammal";
      dog1.setColor("black");
      dog1.displayInfo(dog1.getColor()); 
   }
}

输出

I can eat
I can sleep
I can bark
I am a mammal
My color is black

在此, Animal类内部的type字段受到保护。我们已经使用以下方法从Main类访问了此字段:

dog1.type = "mammal";

这是可能的,因为Animal类和Main类都在同一包中(同一文件)。


Java方法覆写

从上面的示例中,我们知道子类的对象也可以访问其超类的方法。

如果同样的方法在超类和子类都定义 W¯¯ 帽子会怎样?

好吧,在这种情况下,子类中的方法将覆盖超类中的方法。例如,

示例3:方法重写示例

class Animal {
   protected String type = "animal";

   public void eat() {
      System.out.println("I can eat");
   }

   public void sleep() {
      System.out.println("I can sleep");
   }
}

class Dog extends Animal {
  
   @Override
   public void eat() {
      System.out.println("I eat dog food");
   }

   public void bark() {
      System.out.println("I can bark");
   }
}

class Main {
   public static void main(String[] args) {

      Dog dog1 = new Dog();
      dog1.eat();
      dog1.sleep();
      dog1.bark();
   }
}

输出

I eat dog food
I can sleep
I can bark

在这里, eat()在超类Animal和子类Dog中都存在。我们创建了子类Dog的对象dog1

当我们使用dog1对象调用eat() ,将调用Dog内部的方法,而不会调用与类相同的方法。这称为方法覆盖。

在上面的程序中,我们使用了@Override注释来告诉编译器我们正在重写方法。但是,这不是强制性的。在下一个教程中,我们将详细了解方法重写。

如果需要从其子类中调用Animaleat()方法,则可以使用super关键字。

示例4:超级关键字

class Animal {
   public Animal() {
     System.out.println("I am an Animal");
   }

   public void eat() {
     System.out.println("I can eat");
   }
}

class Dog extends Animal {
   public Dog(){
      super();
      System.out.println("I am a dog");
   }

  @Override
  public void eat() {
     super.eat();
     System.out.println("I eat dog food");
  }

   public void bark() {
      System.out.println("I can bark");
   }
}

class Main {
   public static void main(String[] args) {
      Dog dog1 = new Dog();

      dog1.eat();
      dog1.bark();
   }
}

输出

I am an Animal
I am a dog
I can eat
I eat dog food
I can bark

在这里,我们使用了super关键字通过super()来调用构造函数。另外,我们使用super.eat()调用Animal超类的eat()方法。

请注意,在调用构造函数和方法时,使用super的区别。要了解更多信息,请访问Java super关键字


继承类型

继承有五种类型。

  • 单一继承 -B类仅从A类扩展。
  • 多级继承 -B类是从A类扩展 ;然后C类从B类扩展。
  • 层次继承 -类A充当类BCD的超类。
  • 多重继承 -类C从接口AB扩展。
  • 混合继承 -两种或多种继承的混合。

Java不支持通过类的多重继承和混合继承。但是,我们可以通过接口在Java中实现多重继承。我们将在后面的章节中了解接口。


为什么要使用继承?
  • 最重要的用途是代码的可重用性。父类中存在的代码无需在子类中再次编写。
  • 通过方法重写实现运行时多态。在后面的章节中,我们将学习有关多态的更多信息。