Java类的继承
继承是面向对象程序设计的一个重要特性。在现有类的基础上建立新类的处理过程称为继承。由继承而得来的类称为子类,被继承的类称为父类。直接或者间接被继承的类都是父类。子类继承父类的状态和行为,同时也可以修改父类的状态和重写父类的方法,并添加新的状态和行为。
父类与子类
Java中的继承是通过extends关键字来实现的
class B extends A{
...
}
B为A的直接子类,如果A又是另外某个类的子类,那么B同时也是A的间接子类。子类可以继承父类中访问权限设定为public,protected,default的成员属性和成员方法,但是不能继承访问权限为private的成员属性和成员方法,且父类的构造方法不能被继承。
方法重写
Java中的方法重写(override)是指子类重写父类的方法。子类可以改写父类方法所实现的功能,但是子类重写的方法必须与父类中对应的方法具有相同的方法名,返回值类型和参数列表。
所以说方法重写是只是方法的具体实现有所区别。
Java中的方法重写应该注意一下规则:
(1)子类重写方法的名称,返回值类型与参数列表必须与父类被重写的方法一致
(2)子类中重写方法的访问权限不能缩小,例如父类中方法权限是public,子类中只能是public;父类中方法权限是protected,子类中只能是public或者protected;父类中方法权限是默认权限,子类中只能是public或者protected或者默认权限;父类中的私有方法不能被子类继承。
(3)子类重写方法中不能抛出新的异常
方法重写使得Java支持多态,这是面向对象的三大特点(封装,继承,多态)之一
super关键字
super是当前对象里面的父对象的引用(达到可访问权限,除了private)。Java中通过super关键字来实现对父类中被重写方法的调用。
运用super可以调用父类的成员方法,构造方法和成员属性。
(1)调用父类的成员方法:super.method([paramlist])
(2)调用父类的构造方法:super.([paramlist])
(3)调用父类的成员属性:super.filed
class Student {
public int age;
public void std(){ //声明Student类的方法std()
age = 15;
System.out.println("学生平均年龄为:"+age);
}
}
class ThisStudent extends Student{
public int age;
public void std(){
super.std(); //使用super作为父类对象的引用对象来调用父类对象里面的Std()方法
age = 18;
System.out.println("这个学生的年龄为:"+age);
System.out.println(super.age); //使用super作为父类对象的引用对象来调用父类对象中的age值
System.out.println(age);
}
}
public class TestDif {
public static void main(String[] args) {
ThisStudent a = new ThisStudent();
a.std();
}
}
/**
学生平均年龄为:15
这个学生的年龄为:18
15
18
*/
当子类调用一个由父类定义的构造方法时,super语句必须是子类构造方法中第一条被执行的语句。如果子类的构造方法中没有执行super()语句,该构造方法中还是会隐式的使用super()来调用父类中默认的构造方法,并且这条语句在子类的构造方法中都是第一个被执行。
调用父类构造方法的super关键字用法
package Liu;
class Mamal{
public Mamal() { //默认构造方法
System.out.println("我是哺乳动物.");
}
public Mamal(int legs) { //带参数构造方法
System.out.println("我是一只" + legs + "的哺乳动物.");
}
}
class Cat extends Mamal{
public Cat() {
//super(); //这一句写不写都会被执行
System.out.println("我是一只猫.");
}
}
class Sheep extends Mamal{
public Sheep() {
super(4); //调用父类的带参数构造方法
System.out.println("我是一只羊.");
}
}
//测试类
public class TextSuper {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat cat = new Cat();
Sheep dog = new Sheep();
}
}
/**
我是哺乳动物.
我是一只猫.
我是一只4的哺乳动物.
我是一只羊.
*/
如果一个父类没有默认构造方法呢?那么子类不能使用父类的默认构造方法。
会报错:The constructor Mamal() is undefined
那要是在父类没有默认构造方法的情况下子类写默认构造方法呢?
class Cat extends Mamal{
public Cat() {
System.out.println("我是一只"+ x + "猫.");
}
}
会报错:Implicit super constructor Mamal() is undefined. Must explicitly invoke another constructor
class Sheep extends Mamal{
public Sheep() {
super(4); //调用父类的带参数构造方法
System.out.println("我是一只羊.");
}
}
这个不会报错,分析得:如果父类没有默认构造方法,子类在写构造方法时必须继承父类的其他带参数的构造方法,第一句要写super([paramlist]);
为了方便编程,在创建父类的时候最好写出默认构造方法,哪怕是空语句也行
public Mamal() {
...
}
这样给子类写构造函数的时候就不会有这么多烦恼了!
使用super调用父类中的成员方法
package Liu;
class Mamal{
public void call() {
System.out.println("哺乳动物会叫");
}
}
class Sheep extends Mamal{
public void call() {
super.call();//调用父类的call()方法
System.out.println("羊会咩咩叫");
}
}
//测试类
public class TestSuper2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Sheep sheep = new Sheep();
sheep.call();
}
}
/**
哺乳动物会叫
羊会咩咩叫
*/
在子类中,父类中的方法需要通过super关键字进行调用,同时也可以调用父类中被子类隐藏的属性。