【Java】7.0 继承 Inheritance

【简介】
通过类和对象,我们看到了如何非常有效地捕获代码中真实对象的属性和功能

我们常说,代码、对象是对现实的一种抽象反应,对吧

而继承,使我们可以一次又一次地重用代码,而不必重新编写代码。或者换句话说,可以让一些类被归于一种“有共性的模板”
如果我们想编写类似的代码而只更改其中的一小部分怎么办?用继承!

通过继承,我们可以保留所需的功能和属性,然后为额外的内容编写新代码

在Java中,我们可以重用类定义并通过允许一个类(子类或子类)从另一个类(父类或超类)继承来扩展功能

【例子】
还是从车辆说起
我们知道所有车辆都会有一些与之相关的ID(车牌号),品牌和型号。现在让我们来考虑以下车辆:卡车,汽车和自行车————所有这些都具有与之相关的特征。
此外,一辆卡车将有一个承载能力(它可以合法承载的最大重量)和其它的轴,这是它和上述例子中的车辆相比,多出来的“额外功能”
虽然这三种工具是不一样的,但它们有一些共同的特性,我们使用继承作为表示此场景和访问这些特性的手段
这时候,我们就可以创建一个叫做Vehicle的超级类(super class)/父类(parent class),而Truck, Car,Bicycle 就是子类

在我们的示例中,Truck、Car和Bicycle类可以保留Vehicle超类的功能和属性,另外还有一些更具体的类以及它们独特的额外功能(一些方法等等)、

例如,在Car类中,它将具有来自Vehicle的所有方法,即getidNum()、getModel()、setModel()、toString()
它还可以具有特定的方法,例如setNoDoors(),getnoPassengers(),setNoPassengers()等等
这意味着尽管所有类都可以访问Vehicle中的方法和属性,但我们只需为它们编写一次代码(就是编写Vehicle的那次)

【着手使用继承】
让我们先为动物写一个统一的父类

public class Animal   //superclass
{
	//Attributes
	private String breed;
	private String colour;
	private String owner;
	
	//Default constructor
	public Animal()
	{
		this.breed = "None";
		this.colour = "Black";
		this.owner = "Jane Doe";
	}
	//General Constructor
	public Animal(String breed, String colour, String owner)
	{
		this.breed = breed;
		this.colour = colour;
		this.owner = owner;
	}
	//Getter and SEtter methods
	public String getBreed()
	{
		return this.breed;
	}
	public String getColour()
	{
		return this.colour;
	}
	public String getOwner()
	{
		return this.owner;
	}
	public void setBreed(String breed)
	{
		this.breed = breed;
	}
	public void setColour(String colour)
	{
		this.colour= colour;
	}
	public void setOwner(String owner)
	{
		this.owner = owner;
	}
	//Functionality
	public void speak()
	{
		System.out.println("Grr!");
	}
	public String toString()
	{
		String res = "************* \nBreed: " + 
	this.breed +"\nColour: " + this.colour + "\nOwner: " + this.owner;
		return res;
	}
}

然后我们想以此整一个Cat和Dog
这里我们使用Java关键字 extends
这使我们可以继承父(超级)类的所有属性和功能,从而扩展其设计

public class Dog extends Animal
{
  //Attributes related to just Dog
  private boolean chasesSquirrels;
  //default constructor
  public Dog(){
    super(); // call superclass (ANIMAL) default constructor
    this.chasesSquirrels = false;
}
	
}

有了继承之后,我们的代码简化了很多

Cat也是同理

public class Cat extends Animal
{
//Instance Variables
  private boolean worksForSuperVillain;
	
//Default constructor
  public Cat(){
  //super(); // call Animal default constructor
  this.worksForSuperVillain = false;
}
	
	//General constructor
  public Cat(String breed, String colour, String owner, boolean worksForSuperVillain){
  super(breed,colour,owner);
  this.worksForSuperVillain = worksForSuperVillain;
	}
}

【覆盖和添加功能】
一些关于子类父类的规定:
1.我们可以覆盖超类方法的行为,并在当前提供的功能之上添加我们自己的功能
2.我们甚至可以用全新的子类行为替换现有的超类功能

要覆盖超类方法并更改其内容,我们只需在子类中重新编写相同的方法即可,这需要我们在子类中保持相同(或相似)的方法签名
看看在Animal父类中的speak方法:

public void speak()
{
  System.out.println("Grr!");
}

而在我们的子类Dog中,我们编写了相同的方法签名,但是这个方法与Animal中的相比,它具有不同的方法内容

public void speak()
{
  System.out.println("Woof woof!");
} 

需要注意的是,如果我们重写了超类中一个方法,则被重写方法的访问修饰符不能比对其进行重写的方法更严格。(也就是子类重写时,修饰符不能比父类的对应方法严格)

我们的Vehicle父类有两个实例变量,除了类中的所有方法外,还可以传递给子类
注意我们的每个子类的构造函数是,如何使用super()方法,从Vehicle类调用不同的构造函数的。比如:

public Dog()
{
  super(); // call superclass (ANIMAL) default constructor
  this.chasesSquirrels = false;
}
	
public Dog(String breed, String colour, String owner, boolean chasesSquirrels)
{
  super(breed,colour,owner); //Call general constructor in Animal classs
  this.chasesSquirrels = chasesSquirrels;
}

【小结】
1.Java允许我们重用类定义并通过允许一个类(子类或子类)从另一类(父类或超类)继承来扩展功能-这称为继承
2.使用继承时,超类的所有属性和方法在每个子类中均可用
3.关键字extends允许一个类从另一个类进行继承
4.为了调用超类构造函数,我们使用关键字super()
5.我们可以覆盖超类方法的行为,并在当前提供的功能之上添加我们自己的功能

【补充:super()】
super 可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类
与 this 类似,super 相当于是指向当前对象的父类,这样就可以用 super.xxx 来引用父类的成员。因为我们前面说过了,子类可以重写父类的方法。
(子类中的成员变量或方法与父类中的成员变量或方法同名)
当我们有的时候向调用二者同名的方法时,调用父类的需要使用super,否则根据子类优先的原则,会调用子类的对应方法。
super():调用父类中的某一个构造函数(应该为构造函数中的第一条语句),在圆括号中可以写上对应参数

(关于super,这里仅仅是作了一点小小的补充。super和this类似,还有其它的使用方法,这个就不在本篇说了)

posted @ 2021-05-25 20:30  RetenQ  阅读(58)  评论(0编辑  收藏  举报