1.java继承性就是指扩充一个已有的功能,在java要实现继承的关系,可用如下语法完成.
实现继承
class 子类 extends 父类{}
1.对于extends而言,翻译为扩充,但为了理解统一为继承
2.子类又被称为派生类
3.父类又被称为超类
如下代码
子类(Student并没有定义任何操作),而在主类中所使用的全部操作都是由Per类定义的,就证明子类即使不扩充父类也属于维持功能的状态.
package class1;
class Per{
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public String getLnfo(){
return "姓名:"+this.name+",年龄:"+this.age;
}
}
class Student extends Per{ //student类继承Person类
//此类没有定义任何操作方法
}
public class Test1 {
public static void main(String[] args) {
Student student=new Student(); //实例化子类
student.setName("芷若"); //Per类定义
student.setAge(20); //Per类定义
System.out.println(student.getLnfo());
}
}
下面代码
子类对父类的功能进行了扩充(扩充了一个属性和两个方法),子类从外表看是扩充了父类的功能,但是对于以上代码,子类还有一个特点:子类实际上是将父类定义的更加具体化的一种手段,父类表示的范围越大,而子类表示的范围小.
package class1;
class Per{
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
public String getLnfo(){
return "姓名:"+this.name+",年龄:"+this.age+",住址:";
}
}
class Student extends Per{ //student类继承Person类
private String school; //子类扩充的属性
public void setSchool(String school){ //扩充方法
this.school=school;
}
public String getSchool() {
return this.school;
}
}
public class Test1 {
public static void main(String[] args) {
Student student=new Student(); //实例化子类
student.setName("芷若"); //Per类定义
student.setAge(20); //Per类定义
student.setSchool("峨眉"); //student类扩充方法
System.out.println(student.getLnfo()+student.getSchool());
}
}
2.继承的限制
虽然继承可以进行功能的扩充,但是其定义时也会存在若干操作的限制.
限制一:一个子类只能够继承一个父类,存在单继承局限
这其实实际相对于其他语言,在其他语言中,一个子类可以同时继承多个父类,如下代码
class A{}
class B{}
class c extends A,B{} //一个子类继承两个父类
上面操作称为多重继承,实际上就是希望一个子类可以同时继承多个类的功能,java不能支持此类语法,换种方式完成操作.
C类实际上属于(孙)子类,这样一来就相当于B类继承了A类的全部方法,而C类又继承了A和B类的方法,这种操作称为多层继承.所以java只允许多层继承,不允许多重继承,java存在单继承局限.
继承层次不要过多:开发来讲,类之间的继承关系最多不要超过3层.
class A{}
class B extends A{} //B类继承A类
class C extends B{} //C继承B类
限制二:在一个子类继承时,实际上会继承父类操作中的所有操作(属性、方法),但是需要注意,对于所有的非私有(no private)操作属于显示继承(可以直接利用对象操作),而所有的私有操作属于隐式继承(间接完成).
不允许直接访问非私有操作
A类中的msg这个私有属性无法直接访问,但是可以通过setter、getter方法间接进行操作,并且也可以在B类对象中保存msg属性的内容,所以得出结论:私有属性也被继承下来,但却无法直接使用.
限制三:在继承关系中,如果要实例化子类对象,会默认先调用父类构造,为父类中的属性初始化,之后在调用子类构造,为子类中的属性初始化,即默认情况下,子类会找到父类中的无参数构造方法.
代码如下
虽然实例化的是子类对象,但是发现它会默认先执行父类构造,调用父类构造的方法体执行,而后在实例化子类对象,调用子类的构造方法,对于子类的构造而言,就相当于隐含了一个super()的形式.
子类构造方法中隐含一个super().
默认下,子类调用的是父类中的无参构造方法,如果这时候父类没有无参构造,则子类必须通过super()调用指定参数的构造方法.
class B extends A{
public B(){ //子类构造
super(); //调用父类构造,默认隐含
System.out.println("******子类无参数构造******");
}
}
子类调用指定的构造方法
运行代码
任何情况下,子类对象的实例化操作都会调用父类的构造方法,既然super()可以调用父类构造,那么这个语法和this()很相似,super调用父类构造时一定要放在构造方法首行上,所以结论:this和super调用构造方法是不能够同时出现,二选一的关系.
this()和super()都是调用构造方法,都要放在首行.