黑马程序员——JAVA基础---继承

时间:2023-02-12 14:16:52

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

一 继承的概念

继承一般是指晚辈从父辈那里继承财产,也可以说是子女拥有父母所给予他们的东西。在面向对象程序设计中,继承的含义与此类似,所不同的是,这里继承的实体是类而非人。也就是说继承是子类拥有父类的成员。接下来,通过一个具体的实例来说明继承的应用。
在动物园中有许多动物,而这些动物又具有相同的属性和行为,这时就可以编写一个动物类Animal(该类中包括所有动物均具有的属性和行为),即父类。但是对于不同类的动物又具有它自己特有的属性和行为,例如,鸟类具有飞的行为,这时就可以编写一个鸟类Bird,由于鸟类也属于动物类,所以它也具有动物类所共同拥有的属性和行为,因此,在编写鸟类时,就可以使Bird类继承于父类Animal,这样不但可以节省程序开发的时间,而且也提高了代码的可重用性。使用UML类图描述的Bird类与Animal类如图所示。

黑马程序员——JAVA基础---继承

图 使用UML类图描述的Bird类与Animal类

二 创建子类

在类的声明中,可以通过使用关键字extends来显式地指明其父类,其基本的声明格式如下:

[修饰符] class 子类名 extends 父类名
参数说明:
修饰符:可选参数,用于指定类的访问权限,可选值为public、abstract和final。
子类名:必选参数,用于指定子类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。
extends父类名:必选参数,用于指定要定义的子类继承于哪个父类。
例如,定义一个Cattle类,该类继承于父类Animal,即Cattle类是Animal类的子类,具体代码如下:

abstract class Cattle extends Animal {
//……此处省略了类体的代码
}

三 继承的使用原则

子类可以继承父类中所有可被子类访问的成员变量和成员方法,但必须遵循以下原则:

子类能够继承父类中被声明为public和protected的成员变量和成员方法,但不能继承被声明为private的成员变量和成员方法。
子类能够继承在同一个包中的由默认修饰符修饰的成员变量和成员方法。
如果子类声明了一个与父类的成员变量同名的成员变量,则子类不能继承父类的成员变量,此时称子类的成员变量隐藏了父类的成员变量。
如果子类声明了一个与父类的成员方法同名的成员方法,则子类不能继承父类的成员方法,此时称子类的成员方法覆盖了父类的成员方法。
下面将通过一个具体的实例来说明继承的使用原则。
本实例主要实现定义一个动物类Animal及它的子类Bird的操作。
1)创建一个名称为Animal的类,在该类中声明一个成员变量live和两个成员方法eat()与move()。

public class Animal {
public boolean live=true; //定义一个成员变量
public String skin="";
public void eat(){ //定义一个成员方法
System.out.println("动物需要吃食物");
}
public void move(){ //定义一个成员方法
System.out.println("动物会运动");
}
}


}

2)创建一个Animal类的子类Bird类,在该类中隐藏了父类的成员变量skin,并且覆盖了成员方法move()。

public class Bird extends Animal {
public String skin="羽毛";
public void move(){
System.out.println("鸟会飞翔");

}

3)创建一个名称为Zoo的类,在该类的main()方法中创建子类Bird的对象并为该对象分配内存,然后使用对象调用该类的成员方法及成员变量。

public class Zoo {
public static void main(String[] args) {
Bird bird=new Bird();
bird.eat();
bird.move();
System.out.println("鸟有:"+bird.skin);
}
}
提示:在本例程中,eat()方法为从父类Animal继承下来的方法,move()方法为子类覆盖后的成员方法,skin变量为子类的成员变量。

4)运行本实例,其运行结果如图6.7所示。
黑马程序员——JAVA基础---继承

图6.7 实例的运行结果

四 使用this关键字

当局部变量和成员变量的名字相同时,成员变量就会被隐藏,这时如果想在成员方法中使用成员变量,就必须使用关键字this。关键字this的基本格式如下:

this.成员变量名
this.成员方法名()
在Fruit类中定义一个成员变量color,并且在该类的成员方法中定义一个局部变量color,这时,如果想在成员方法中使用成员变量color,就需要使用this关键字。

public class Fruit {
public String color="绿色"; //定义颜色成员变量
//定义收获的方法
public void harvest(){
String color="红色"; //定义颜色局部变量
System.out.println("水果是:"+color+"的!");//此处输出的是局部变量color
System.out.println("水果已经收获……");
System.out.println("水果原来是:"+this.color+"的!");
//此处输出的是成员变量color
}
}

执行结果如下:
水果是:红色的!
水果已经收获……
水果原来是:绿色的!

五 使用super关键字

子类可以继承父类的非私有成员变量和成员方法(不是以private关键字修饰的)作为自己的成员变量和成员方法,但是,如果子类中声明的成员变量与父类的成员变量同名,则子类不能继承父类的成员变量,此时称子类的成员变量隐藏了父类的成员变量。如果子类中声明的成员方法与父类的成员方法同名,并且方法的返回值及参数个数和类型也相同,则子类不能继承父类的成员方法,此时称子类的成员方法覆盖了父类的成员方法。这时,如果想在子类中访问父类中被子类覆盖或隐藏的成员方法或变量时,就可以使用super关键字。super关键字主要有以下两种用途。

1.调用父类的构造方法
子类可以调用由父类声明的构造方法,但是必须在子类的构造方法中使用super关键字,具体的语法格式如下:
super([参数列表]);
如果父类的构造方法中包括参数,则参数列表为必选项,用于指定父类构造方法的入口参数。
在Animal类中添加一个默认的构造方法和一个带参数的构造方法。
public Animal(){
}
public Animal(String strSkin){
skin=strSkin;
}
这时,如果想在子类Bird中使用父类的带参数的构造方法,则需要在子类Bird的构造方法中输入以下代码:

public Bird(){
super("羽毛");
}

2.操作被隐藏的成员变量和被覆盖的成员方法
如果想在子类中操作父类中被隐藏的成员变量或被覆盖的成员方法,也可以使用super关键字,具体格式如下:
super.成员变量名
super.成员方法名([参数列表])
例如,想在子类Bird的方法中改变父类Animal的成员变量skin的值,可以使用以下代码:
super.skin=”羽毛”;
如果想在子类Bird的方法中使用父类Animal的成员方法move(),可以使用以下代码:
super.move();