Java继承多个类的例子 - 极悦
首页 课程 师资 教程 报名

Java继承多个类的例子

  • 2022-04-29 10:00:44
  • 2986次 极悦

java多个类继承的方法有哪些?极悦小编来给大家举例说明。

假设有三个java类,ClassA-ClassB-ClassC,ClassC在最底端。先看例子:

public class ClassA {undefined
public void fun1(){undefined
System.out.println(“A-fun1″);
}
public void fun2(){undefined
System.out.println(“A-fun2″);
}
public void fun3(){undefined
System.out.println(“A-fun3″);
}
public ClassA(){undefined
System.out.println(“A-ClassA”);
}
}
public class ClassB extends ClassA{undefined
public void fun1(){undefined
System.out.println(“B-fun1″);
}
public ClassB(){undefined
System.out.println(“B-ClassB”);
}
public ClassB(String str){undefined
System.out.println(“B-ClassB(String)”);
}
}
public class ClassC extends ClassB{undefined
public void fun1(){undefined
System.out.println(“C-fun1″);
}
public void fun2(){undefined
System.out.println(“C-fun2″);
System.out.println(“————-super.fun1()前————————”);
super.fun1();
System.out.println(“—————-super.fun1()后———————”);
}
public ClassC(){undefined
super(“aaa”);
System.out.println(“C-ClassC”);
}
public static void main(String[] agrs){undefined
ClassA c1 = new ClassC();
c1.fun1();
c1.fun2();
c1.fun3();
System.out.println(“————————————-”);
ClassB c2 = new ClassC();
c1.fun2();
c2.fun1();
}
}

输出:

A-ClassA
B-ClassB(String)
C-ClassC
C-fun1
C-fun2
————-super.fun1()前————————
B-fun1
—————-super.fun1()后———————
A-fun3
————————————-
A-ClassA
B-ClassB(String)
C-ClassC
C-fun2
————-super.fun1()前————————
B-fun1
—————-super.fun1()后———————
C-fun1

c1这个对象,执行时的类型是ClassC。

首先说构造方法。如果不写super(),相当于默认写了个super(),如果new ClassC()会从最顶端的类开始初始化,依次调用

A-ClassA()

B-ClassB()

C-ClassC()

而此处,我们在ClassC中写了个

super(“aaa”);

就会去调用B中的带参数的构造方法,而不再调用无参的构造方法。所以,当new ClassC()时,

我们得到的结果是:

A-ClassA

B-ClassB(String)

C-ClassC

特别要注意的是,super()只能在构造方法中使用,而且只能在第一行使用。this()也是同样的道理。

而我们在C的fun2()中调用了super.fun1();

则再一次调用了C的父类,也就是B的fun1(),输出一个B-fun1。

再来说三个方法的覆盖问题。

B覆盖了fun1(),C覆盖了fun1(),fun2()

也就是说,虽然B中没有fun2(),而且C继承了B,但C同样可以覆盖fun2()。

说明了,凡是整个继承系统中有的方法,无论上一级类是否有,都可以覆盖。

按照这种写法

ClassA c1 = new ClassC();

B类中的方法,如果不是C类用了super.fun1(),是绝不可能调用到的。

也就是,如果不在C类的fun2()中写super.fun1(),输出结果应该是:

A-ClassA
B-ClassB(String)
C-ClassC
C-fun1
C-fun2
A-fun3
————————————-
A-ClassA
B-ClassB(String)
C-ClassC
C-fun2
C-fun1

而从ClassB c2 = new ClassC()来看,也不可能调用到C类中的方法,因为执行时的类型为C。

下面再看一个例子:

public class Class1 {undefined
int a = 1;
static int b = 2;
private int i = 1;
int j = 4;
{undefined
System.out.println(“normal—Class1–(a==”+a+”)–(b==”+b+”)”);
}
static{undefined
//System.out.println(“static—MClass1–”+a+”–”+b);//这里不认识非静态变量
System.out.println(“static—Class1–(b==”+b+”)”);
}
public Class1(){undefined
System.out.println(“construct—Class1–(a==”+a+”)—(b==”+b+”)”);
System.out.println(“fun1—Class1–(this.i==”+this.i+”)”);
System.out.println(“fun1—Class1–(this.j==”+this.j+”)”);
this.fun1();
}
public void fun1(){undefined
System.out.println(“fun1—Class1–(i==”+i+”)”);
System.out.println(“fun1—Class1–(j==”+j+”)”);
}
}
public class Class2 extends Class1{undefined
int c = 1;
static int d = 2;
{undefined
System.out.println(“normal—Class2–(a==”+a+”)–(b==”+b+”)”);
System.out.println(“normal—Class2–(c==”+c+”)–(d==”+d+”)”);
}
static{undefined
//System.out.println(“static—MClass1–”+a+”–”+b);//这里不能调用非静态变量
System.out.println(“static—Class2–(b==”+b+”)”);
System.out.println(“static—Class2–(d==”+d+”)”);
}
public Class2(){undefined
System.out.println(“construct—Class2–(a==”+a+”)—(b==”+b+”)”);
System.out.println(“construct—Class2–(c==”+c+”)—(d==”+d+”)”);
}
}
public class Class3 extends Class2{undefined
int e = 1;
static int f = 2;
private int i = 2;
int j = 3;
{undefined
System.out.println(“normal—Class3–(a==”+a+”)–(b==”+b+”)”);
System.out.println(“normal—Class3–(c==”+c+”)–(d==”+d+”)”);
System.out.println(“normal—Class3–(e==”+e+”)–(f==”+f+”)”);
}
static{undefined
//System.out.println(“static—MClass1–”+a+”–”+b);//这里不能调用非静态变量
System.out.println(“static—Class3–(b==”+b+”)”);
System.out.println(“static—Class3–(d==”+d+”)”);
System.out.println(“static—Class3–(f==”+f+”)”);
}
public Class3(){undefined
System.out.println(“construct—Class3–(a==”+a+”)—(b==”+b+”)”);
System.out.println(“construct—Class3–(c==”+c+”)—(d==”+d+”)”);
System.out.println(“construct—Class3–(e==”+e+”)—(f==”+f+”)”);
i=222;
j=333;
}
public void fun1(){undefined
System.out.println(“fun1—Class3–(i==”+i+”)”);
System.out.println(“fun1—Class3–(j==”+j+”)”);
}
public static void main(String[] agrs){undefined
new Class3();
}
}

输出结果:

static—Class1–(b==2)
static—Class2–(b==2)
static—Class2–(d==2)
static—Class3–(b==2)
static—Class3–(d==2)
static—Class3–(f==2)
normal—Class1–(a==1)–(b==2)
construct—Class1–(a==1)—(b==2)
fun1—Class1–(this.i==1)
fun1—Class1–(this.j==4)
fun1—Class3–(i==0)
fun1—Class3–(j==0)
normal—Class2–(a==1)–(b==2)
normal—Class2–(c==1)–(d==2)
construct—Class2–(a==1)—(b==2)
construct—Class2–(c==1)—(d==2)
normal—Class3–(a==1)–(b==2)
normal—Class3–(c==1)–(d==2)
normal—Class3–(e==1)–(f==2)
construct—Class3–(a==1)—(b==2)
construct—Class3–(c==1)—(d==2)
construct—Class3–(e==1)—(f==2)

这里有两个知识点要说明:

1.类的初始化顺序是:

(静态变量、静态初始化块)>(变量、初始化块)>构造器

而根据上面的输出结果看出,三个类的静态初始化块执行完了,再依次是:

Class1的非静态初始化块

Class1的构造器

Class2的非静态初始化块

Class2的构造器

Class3的非静态初始化块

Class3的构造器

值得注意的是,静态的方法和初始化块中都不能直接调用非静态变量!

2.写了一个小插曲,如果Class1中的fun1()被Class2中的fun1()覆盖,当Class1初始化(也就是调用Class1的构造器)时,

在Class1的构造器中调用this.fun1();会调到谁的?

两个类都有两个变量i、j,其中i是private

在Class1的构造器中调用this.i和this.j又会调到谁的?

记住一点,如果是调用方法,就看执行时的类型,如果是调用变量,就看编译时的类型。

所以说,fun1()会调用到 Class3的,而i、j会调用到Class1的。

又由于,所有的变量和方法都会最先在内存中开辟空间,变量初始值默认为0或null,

例如定义了int i=3 相当于写了先int i=0后面再写i=3;

当Class1初始化时,Class3并没有完成初始化,仅完在了int i=0这个步骤。

所以,在Class1初始化时调用Class3的fun1()输出Class3的i和j的值均为0。

而在Class1的构造器中输出i和j是属于Class1的,在执行构造器前就已经完成了赋值

其实,这儿不写this效果是一样的。

以上就是关于“Java继承多个类的例子”介绍,大家如果对此比较感兴趣,想了解更多相关知识,不妨来关注一下极悦的Java教程,里面的课程内容细致全面,通俗易懂,很适合小白学习,希望对大家的学习能够有所帮助哦。

选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交