(1)成员变量的继承与隐藏
基于父类创建子类时,子类可以继承父类的成员变量和成员方法。但是,如果在父类和子类中同时声明了一个同名变量时,则这两个变量在程序运行时同时存在。也就是说,子类在使用父类的同名变量时,父类中的同名变量只是被隐藏了。
示例代码如下:
class Person {
String name;
int age;//声明两个成员变量
public Person(String name, int age) { //有参构造方法
this. name =name;this. age =age;}
public Person() { //无参构造方法
this. name ="person name";this. age =23;}
void pprint() { //成员方法,此时显示的是父类中的成员变量
System. out. println("class:Person;"+"Name:"+this. name+";age:"+this. age);
}
}
class Student extends Person{ //基于Person类定义Student子类
String name; //在派生类中声明自己的成员变量
int classno; //声明新成员变量
public Student() { //无参构造方法
this. name ="student name";this. age =20;}
public Student(String name, int age, int classno){ //有参构造方法
this. name =name;
this. age =age;
this. classno =classno;
}
void sprint() { //成员方法,此时显示的是子类中的成员变量
System. out. println("class:Student;"+"Name:"+this. name + ";age:"+this. age +"; classno:"+this. classno);
}
}
public class VarInherit { //声明公共类
public static void main(String[]args){
Student obj1 = new Student( ); //调用无参构造方法创建对象
Student obj2 = new Student("LiXiao",18,1);//调用有参构造方法创建对象
obj1. pprint( );obj2. pprint( ); //调用父类的成员方法
obj1. sprint( );obj2. sprint( ); //调用子类的成员方法
}
}
程序的运行结果:class:Person;Name:person name;age:20
class:Person;Name:person name;age:18
class:Student;Name:student name;age:20;classno:0
class:Student;Name:LiXiao;age:18;classno:1
解释说明:
①由于Student子类中未定义成员变量age,因此,该成员变量源自其父类,这说明子类可以继承父类的成员变量。
②name变量同时在父类和子类中进行了声明。当我们通过“Student obj1 =new Student();”语句创建对象obj1时,系统会首先调用父类的无参构造方法,然后再调用子类的无参构造方法,故父类中的name 被赋值“person name”,子类中的name被赋值“student name”,而公共成员变量age被赋值20。另外,由于子类成员变量classno未被显式赋值,故输出系统自动为其初始化为默认值0。
(2)方法的继承与覆盖
子类可以继承父类中所有可以被子类访问的成员方法,但是如果子类重新定义了从父类继承来的方法,那么父类的这个方法在子类中将不复存在,此时称子类方法覆盖了父类的方法,简称方法覆盖(override)。
示例代码如下:
class Parentclass { //声明父类
void pprint( ) { //声明成员方法
this. print( );
this. print1( 0) ;
}
void print() {//声明同类型、同名、同参数成员方法
System. out. println("父类:同类型、同名、同参数成员方法!");}
void print1(int a) { //声明同类型、同名但参数不同的成员方法
System. out. println("父类:同类型、同名但参数不同的成员方法!");}
}
class Subclass extends Parentclass {//基于Parentclass 类定义Subclass子类
void sprint( ) { //声明成员方法
this. print( );
this. printl();
}
void print() { //声明同类型、同名、同参数成员方法
System. out. println("子类:同类型、同名、同参数成员方法!");}
void print1() { //声明同类型、同名但参数不同的成员方法
System. out. println("子类:同类型、同名但参数不同的成员方法!");}
}
public class MethodInherit { //声明公共类
public static void main(String[]args){
Subclass obj =new Subclass();
obj. pprint(); //调用父类的成员方法
obj. sprint( ); //调用子类的成员方法
}
}
程序的运行结果:
子类:同类型、同名、同参数成员方法!
父类:同类型、同名但参数不同的成员方法!
子类:同类型、同名、同参数成员方法!
子类:同类型、同名但参数不同的成员方法!
解释说明:
①使用子类创建对象时,可以直接引用父类中的方法,如利用“obj. pprint();”语句调用父类中的pprint 成员方法。这体现了方法的继承性。
②要使子类中的方法完全覆盖父类中的方法,方法的类型、名称和参数必须完全相同(如两个print方法),否则,任何一项不同均不能覆盖(如两个printl方法)。
继承的注意事项:
①子类可以继承父类中的成员变量,包括私有成员变量,但不能直接访问。
②构造子类对象的时候会自动调用父类的无参构造方法,用于初始化从父类中继承的成员变量。
③在Java 语言中的类只支持单继承,也就是一个类只能有一个父类,但一个父类可以有多个子类。
④只有满足子类is a父类的逻辑关系才能继承,不能滥用继承。