11、当你想让一个子类同时继承两个父类时,尝试采取间接继承方案,并使用查看效果。
第一种方案,间接继承
public class Main
{
public static void main(String[] args)
{
//我想让two既有One的一些变量,又有One2喝醉的方法
//因为Two已经继承了One,我不想改,只能让没有继承任何东西的One继承One2
//如果One也继承了一个父类,那我只能采用组合的方法,
//如果觉得组合很麻烦,那我就只能把One2定义成一个接口,并且把它的drink方法定义成default方法
Two two = new Two();
two.drink();
}
}
class One extends One2
{
public String publi = "公共";
protected String prote = "protected";
String defau = "默认";
private String priva = "private";
//静态初始化块
static
{
System.out.println("One的静态初始化块");
}
//实例初始化块
{
System.out.println("One的实例初始化块");
}
//构造器
public One()
{
System.out.println("One的无参数构造器");
}
//提供一种类方法
static void show()
{
System.out.println("啊,我是父类");
}
}
class Two extends One
{
//静态初始化块
static
{
System.out.println("Two的静态初始化块");
}
//实例初始化块
{
System.out.println("Two的实例初始化块");
}
//构造器1
public Two()
{
super();
System.out.println("Two的无参数构造器");
}
public Two(String info)
{
System.out.println("Two的有参数构造器");
}
}
class One2
{
public void drink()
{
System.out.println("One2喝醉了");
}
}
第二种方案:组合,这里就不写了,就是给Two的构造器中传入一个One2实例
第三种方案:把One2定义成接口,把drink方法定义成default方法,Two实现这个接口
public class Main
{
public static void main(String[] args)
{
//我想让two既有One的一些变量,又有One2喝醉的方法
//因为Two已经继承了One,我不想改,只能让没有继承任何东西的One继承One2
//如果One也继承了一个父类,那我只能采用组合的方法,
//如果觉得组合很麻烦,那我就只能把One2定义成一个接口,并且把它的drink方法定义成default方法
Two two = new Two();
two.drink();
}
}
class One
{
public String publi = "公共";
protected String prote = "protected";
String defau = "默认";
private String priva = "private";
//静态初始化块
static
{
System.out.println("One的静态初始化块");
}
//实例初始化块
{
System.out.println("One的实例初始化块");
}
//构造器
public One()
{
System.out.println("One的无参数构造器");
}
//提供一种类方法
static void show()
{
System.out.println("啊,我是父类");
}
}
class Two extends One implements One2
{
//静态初始化块
static
{
System.out.println("Two的静态初始化块");
}
//实例初始化块
{
System.out.println("Two的实例初始化块");
}
//构造器1
public Two()
{
super();
System.out.println("Two的无参数构造器");
}
public Two(String info)
{
System.out.println("Two的有参数构造器");
}
}
interface One2
{
default void drink()
{
System.out.println("One2喝醉了");
}
}
子类直接只能调用一次自己的构造器,也直接的话只能调用一次父类的构造器,但是间接的话可以叠加的调用构造器,
this()指向的构造器中也有一个this(),
不过如果子类通过super()跳转到了父类就不能再跳转回子类了。
强化:实现子类间接继承自己的4个构造器,实现子类间接继承父类的4个构造器,其实也就是让子类能够既调用多个自己的构造器,和多个父类的构造器
public class Main
{
public static void main(String[] args)
{
//尝试调用子类的默认构造器,看看父类的构造器会不会有反应
Two two = new Two();
}
}
class One
{
public String publi = "公共";
protected String prote = "protected";
String defau = "默认";
private String priva = "private";
//静态初始化块
static
{
System.out.println("One的静态初始化块");
}
//实例初始化块
{
System.out.println("One的实例初始化块");
}
//构造器
public One()
{
this("开心");
System.out.println("One的无参数构造器");
}
public One(String info)
{
this("a","b");
System.out.println("One的info构造器");
}
public One(String info , String info2)
{
System.out.println("One的info和info2构造器");
}
//提供一种类方法
static void show()
{
System.out.println("啊,我是父类");
}
}
class Two extends One
{
//静态初始化块
static
{
System.out.println("Two的静态初始化块");
}
//实例初始化块
{
System.out.println("Two的实例初始化块");
}
//构造器1
public Two()
{
//调用默认构造器,将会调用多个父类构造器
super();
System.out.println("Two的无参数构造器");
}
public Two(String info)
{
System.out.println("Two的有参数构造器");
}
}
从运行结果来看,调用子类的无参数构造器,会先进入父类的无参数构造器,然后通过父类的this(info)跳转到父类的单个参数的构造器中,在单个参数的构造器中通过this(info1,info2)跳转到两个参数的构造器中,然后执行两个参数的构造器,返回执行一个参数的构造器,最后返回执行无参数构造器,这里的例子是子类间接调用父类的多个不同的构造器,直接来看的话子类只是调用了父类的无参数构造器。
对上面的程序稍作修改
public class Main
{
public static void main(String[] args)
{
//尝试调用子类的默认构造器,看看父类的构造器会不会有反应
Two two = new Two("a","B");
}
}
class Two
{
//静态初始化块
static
{
System.out.println("Two的静态初始化块");
}
//实例初始化块
{
System.out.println("Two的实例初始化块");
}
//构造器1
public Two()
{
//调用默认构造器,将会调用多个父类构造器
System.out.println("Two的无参数构造器");
}
public Two(String info)
{
this();
System.out.println("Two的info参数构造器");
}
public Two(String info1, String info2)
{
this("哈哈");
System.out.println("Two的info1和info2参数构造器");
}
}
结果也是一样,子类直接调用自己的一个单参数构造器,却间接的调用了无参数构造器