一、继承
继承就是一种由已有类创建新类,在已有类的基础上扩展功能。
1、只能单一继承,即子类只能有一个父类,但是可以多层继承。
2、子类中出现了同名称的成员变量,会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。
3、子类可以对父类的方法进行重写(即方法的返回类型、方法名、参数列表完全相同时,仅方法体不一样),子类对父类的方法重写之后,创建子类对象,直接调用的是子类重写的方法,这时要想调用父类的方法就要在子类方法中用到super.方法名(参数列表)。另有调用父类中被重写的构造方法时super语句要写在子类构造方法第一行。
代码演示:
public class Sub {
String name="老子";
public Sub(){
System.out.println("老子:哈哈,我是老子,不信你去百度翻译查‘老子’怎么翻译");
}
public Sub(int i){
System.out.println("老子:儿子,孙子在哪?");
}
Sub(String s)
{
System.out.println(s);
}
void f(){
System.out.println("老子:小子,你调用的是老子的方法");
}
public static void main(String[] args) {
Son1 s=new Son1();//如果父类只有有参的构造函数,即使子类有无参构造函数,这样写会报错。
Son1 s1=new Son1(1);
s1.f();
System.out.println(s1.name);//子类变量覆盖了父类变量
Son1 s2=new Son1("儿子");//将默认调用父类无参构造函数
}
}
class Son1 extends Sub{
String name="儿子";
Son1(){
System.out.println("儿子:查了,老子是您“me”呀!");
}
Son1(int i){
super(i);//不写这句默认调用的是父类无参构造函数
System.out.println("儿子:说的跟儿子你有媳妇似的!");
}
Son1(String s)
{
System.out.println(s);
}
void f(){//子类覆盖父类方法,不能缩小访问权限。
System.out.println("儿子:我长大了,要用自己的方法");
super.f();//调用父类的方法,可以不放在第一行
}
}
运行结果:
老子:哈哈,我是老子,不信你去百度翻译查‘老子’怎么翻译
儿子:查了,老子是您“me”呀!
老子:儿子,孙子在哪?
儿子:说的跟儿子你有媳妇似的!
儿子:我长大了,要用自己的方法
老子:小子,你调用的是老子的方法
儿子
老子:哈哈,我是老子,不信你去百度翻译查‘老子’怎么翻译
儿子
对于无参数的父类构造器,会被子类默认调用;
对于带参数的父类构造器,子类必须使用关键字super显示地调用,并配以适当的参数。
子类覆盖父类方法,可以修改方法作用域修饰符,但只能把方法的作用域放大。
父类只有有参数构造函数,子类在构造方法中必须要显示调用父类相应的构造函数,否则编译出错。
静态方法和实例方法不能相互隐藏。
有多层继承时首先根基类中的static初始化,然后是下一个导出类,以此类推,static初始化完成之后。然后实例变量和构造器从根基类到下一个导出类一步步初始化调用。
二、组合
在新类中产生现有类的对象,由于新类是由现有类的对象组成的,这种方法称之为组合。
注意区分组合和继承:
代码演示如下所示:
class Plate{
Plate(int i){
System.out.println("Plate constructor"+i);
}
}
class DinnerPlate extends Plate{
DinnerPlate(int i){
super(i);
System.out.println("DinnerPlate constructor"+i);
}
}
class Utensil{
Utensil(int i){
System.out.println("Utensil constructor"+i);
}
}
class Spoon extends Utensil{
Spoon(int i){
super(i);
System.out.println("Spoon constructor"+i);
}
}
class Fork extends Spoon{
Fork(int i){
super(i);
System.out.println("Fork constructor"+i);
}
}
class Knife extends Fork{
Knife(int i){
super(i);
System.out.println("Knife constructor"+i);
}
}
class Custom{
Custom(int i){
System.out.println("Custom constructor"+i);
}
}
public class PlaceSetting extends Custom{
private Spoon sp;//组合
private Fork frk;//组合
private DinnerPlate pl;//组合
private Knife kn;
public PlaceSetting(int i){
super(i+1);//调用父类构造方法
sp=new Spoon(i+2);
frk=new Fork(i+3);//从根基类到派生类一步步调用构造函数
kn=new Knife(i+4);//从根基类到派生类一步步调用构造函数
pl=new DinnerPlate(i+5);
System.out.println("PlaceSetting constructor"+i);
}
public static void main(String[] args) {
PlaceSetting x=new PlaceSetting(9);
}
}
运行结果:
Custom constructor10
Utensil constructor11
Spoon constructor11
Utensil constructor12
Spoon constructor12
Fork constructor12
Utensil constructor13
Spoon constructor13
Fork constructor13
Knife constructor13
Plate constructor14
DinnerPlate constructor14
PlaceSetting constructor9