方法的重写/覆盖
方法重写的原则
1.方法名与父类完全相同
2.参数列表完全相同 (否则就不是重写而是重载了)
3.返回值类型可以跟父类一致,也可以是父类的其他子类
4.访问权限要相同或者放大
public class SE {
String name;
public void code(){
System.out.println(this.name + "正在敲代码");
}
}
--------------------------------------------------------------------------------
public class Stu extends SE{
double score;
@Override
public void code() {//子类的访问权限要大于等于父类的权限
super.code();
}
}
public class SE {
public SE code(){//返回自己
return null;
}
}
--------------------------------------------------------------------------------
public class Stu extends SE{
double score;
@Override
public Stu code() {//返回父类其中的一个子类
return null;
}
}
--------------------------------------------------------------------------------
public class Worker extends SE {
@Override
public SE code(){//返回父类
return null;
}
}
继承下的构造方法的执行
无参构造
public class A {
public A(){
//先会默认调用super();
System.out.println("这是A的无参构造");
}
}
public class B extends A{
public B(){
//先会默认调用super();
System.out.println("这是B的无参构造");
}
}
public class C extends B {
public C (){
//先会默认调用super();
System.out.println("这是C的无参构造");
}
}
public class Demo {
public static void main(String[] args){
new C();
}
}
/*输出
这是A的无参构造
这是B的无参构造
这是C的无参构造
*/
可见,先执行了父类A的构造方法,再B,再C
这是因为执行C的构造函数时,会先默认调用super();
带参构造
再来看以下程序:
public class A {
int a;
public A(int a){
System.out.println("这是A的带参构造 a = " + a);
System.out.println("这是A的带参构造 this.a = " + this.a);
this.a = a;
System.out.println("这是A的带参构造 this.a = " + this.a);
}
}
public class B extends A{
int b;
public B(int a,int b){
super(a);//这实际上是A的构造函数
System.out.println("这是B的带参构造 b = " + b);
System.out.println("这是B的带参构造 this.b = " + this.b);
this.b = b;
System.out.println("这是B的带参构造 this.b = " + this.b);
}
}
public class C extends B {
int c;
public C (int c){
super(c * 2,c);//这实际上是B的构造函数
System.out.println("这是C的带参构造 c = " + c);
System.out.println("这是C的带参构造 this.c = " + this.c);
this.c = c;
System.out.println("这是C的带参构造 this.c = " + this.c);
}
}
public class Demo {
public static void main(String[] args){
new C(111); //执行已有的,而非创建父类
//调用C,C执行AB,实际只在C空间内调用
}
}
/*输出
这是A的带参构造 a = 222
这是A的带参构造 this.a = 0
这是A的带参构造 this.a = 222
这是B的带参构造 b = 111
这是B的带参构造 this.b = 0
这是B的带参构造 this.b = 111
这是C的带参构造 c = 111
这是C的带参构造 this.c = 0
这是C的带参构造 this.c = 111
*/
父类子类之间的关系
public class A {
public A(){
System.out.println("A是A的类型吗?" + (this instanceof A));
System.out.println("A是B的类型吗?" + (this instanceof B));
System.out.println("A是C的类型吗?" + (this instanceof C));
}
}
public class B extends A{
public B(){
super();//这实际上是A的构造函数
System.out.println("B是A的类型吗?" + (this instanceof A));
System.out.println("B是B的类型吗?" + (this instanceof B));
System.out.println("B是C的类型吗?" + (this instanceof C));
}
}
public class C extends B {
public C (){
super();//这实际上是B的构造函数
System.out.println("C是A的类型吗?" + (this instanceof A));
System.out.println("C是B的类型吗?" + (this instanceof B));
System.out.println("C是C的类型吗?" + (this instanceof C));
}
}
public class Demo {
public static void main(String[] args){
new A();
System.out.println("---------");
new B();
System.out.println("---------");
new C();
}
}
/*
A是A的类型吗?true
A是B的类型吗?false
A是C的类型吗?false
---------
A是A的类型吗?true
A是B的类型吗?true
A是C的类型吗?false
B是A的类型吗?true
B是B的类型吗?true
B是C的类型吗?false
---------
A是A的类型吗?true
A是B的类型吗?true
A是C的类型吗?true
B是A的类型吗?true
B是B的类型吗?true
B是C的类型吗?true
C是A的类型吗?true
C是B的类型吗?true
C是C的类型吗?true
*/
输出结果从侧面反映出 如果调用了C的构造函数,那么创建出的AB其实就是C,在C的内存中
如果创建了C,C的内存分布如下图: