Java 父类和子类关系:成员变量(覆盖)、构造方法、成员方法(覆盖)、类型转换等

详细解释Java中父类和子类的关系

  • 1 定义类
  • 2 构造方法
  • 3 成员变量
  • 4 成员方法
  • 5 类型转换
  • 6 隔代继承

主要包括:成员变量(覆盖)、构造方法、成员方法(覆盖)、类型转换

1 定义类

定义A、B、C、D四个类,B、C继承A,D继承B
class A{
	public int a;
	private int b;
	protected int c;
	// 两个构造方法
	public A() {
		a = 1;
		b = 2;
		c = 3;
		System.out.println("父类默认构造方法");
	}
	public A(int a, int b,  int c) {
		this.a = a;
		this.b = b;
		this.c = c;
		System.out.println("父类重载构造方法");
	}
	public void myPrint1() {
		System.out.println("父类_1");
	}
	public void myPrint2() {
		System.out.println("父类_2");
	}
}

// 子类
class B extends A{
	public int d;
	// 构造函数
	public B() {
		super();
		d = 3;
		System.out.println("子类默认构造方法");
	}
	public B(int a, int b, int c, int d) {
		super(a, b, c);
		this.d = d;
		System.out.println("子类重载构造方法");
	}
	public void myPrint1() {
		System.out.println("子类B_1");
	}
	public void printB() {
		System.out.println("a = "+this.a+"; c="+this.c);
	}
	public void printP(){
		super.myPrint1();
	}
}

// 子类
class C extends A{
	public int a;  // 覆盖父类成员变量
	public C() {
		super();
	}
	public C(int a) {
		super();
		this.a = a;
	}
	public void myPrint1() {
		System.out.println("子类C_1");
	}
	public void printC() {
		System.out.println("子类a = "+this.a+"; 父类a="+super.a);
	}
}

// “孙”子类
class D extends B{
	
}

2 构造方法

子类在新建对象时,首先调用父类的构造方法,然后调用自己的构造方法。其中super()可不写,但是为了避免不必要的麻烦还是写上。

B B1 = new B();
/*
父类默认构造方法
子类默认构造方法
*/
B B2 = new B(5,4,3,2);
/*
父类默认构造方法
子类重载构造方法
*/

3 成员变量

1、子类可以继承父类public和protected修饰的成员变量和成员方法。

B B1 = new B(3, 4, 5);
System.out.println(B1.a);  // 输出:3
System.out.println(B1.c);  // 输出:5
System.out.println(B1.d);  // 输出:6
//System.out.println(B1.b);  // 报错(java.lang.Error:Unresolved compilation problem)

2、 子类覆盖父类的成员变量

C C1 = new C();
C C2 = new C(5);
C1.printC();  // 输出:子类a = 0; 父类a=1
C2.printC();  // 输出:子类a = 5; 父类a=1
System.out.println(C2.a);  // 输出:5

4 成员方法

1、非同名方法

B B1 = new B(3, 4, 5, 6);
B1.myPrint2();  // 输出:父类_2

2、同名方法:子类覆盖父类方法

B B1 = new B(3, 4, 5, 6);
B1.myPrint1();  // 输出:子类B_1 

如何调用父类被覆盖的方法,类似成员变量,在类B的定义中,定义一个新的函数,使用super关键词。

public void printP(){
	super.myPrint1();
} 

B1.printP(); // 输出:父类_1

5 类型转换

1、子类转父类–>向上转型
无需转换,生成的对象类别为子类,只能调用父类和子类同时拥有的变量和成员方法。

A A1 = new B(3, 4, 5, 6);  
System.out.println(A1.getClass());  // 输出:class mytest.B
A1.myPrint1();  // 输出:子类B_1,调用了子类的方法
A1.myPrint2();  // 输出:父类_2
// A1.printB();  // 报错(java.lang.Error:Unresolved compilation problem)
// System.out.println(A1.d);  // 报错(java.lang.Error:Unresolved compilation problem)
A A2 = new C(7);
System.out.println(A2.a);  // 输出:1,却不是7
System.out.println(A2.c);  // 输出:3

注意:存在覆盖的情况时,成员方法调用子类的,而成员变量却是父类的值。子类的同名属性被隐藏,父类的同名方法被覆盖。简单点来说,用子类来创建父类对象只是将父类被覆盖的方法替换为子类的方法。
2、将A1,A2进行强制转换–>向下转型

A A10 = new B(3, 4, 5, 6);
B A1 = (B) A10;
System.out.println(A1.getClass());  // 输出:class mytest.B
A1.myPrint1();  // 输出:子类B_1,调用了子类的方法
A1.myPrint2();  // 输出:父类_2
A1.printB();  // 输出:a = 3; c=5
System.out.println(A1.d);  // 输出:6
A A20 = new C(7);
C A2 = (C) A20;
System.out.println(A2.a);  // 输出:7
System.out.println(A2.c);  // 输出:3

对比1和2中的变化,总结来说相当于完全转换成子类,相当于"B A1 = new B();“和"C A2 = new C();”。
3、 父类强制转子类
非法操作,报错:java.lang.ClassCastException。

A A1 = new A();
B B1 = (B) A1;  // 报错( java.lang.ClassCastException:mytest.A cannot be cast to mytest.B)

4、不同子类相互转换
非法操作,报错:java.lang.Error: Unresolved compilation problem。

B B1 = new B();
C C1 = (C) B1;  // 报错(java.lang.Error: Unresolved compilation problem)
B B2 = new A();  // 报错(java.lang.Error: Unresolved compilation problem)

可以进行转换,但是只有两个所共有的成员方法,若有重复的以赋值对象的为准。成员变量是父类的值。

A B2 = new B();
C C2 = new C(5);
B2 = C2;
System.out.println(B2.getClass());  // 输出:class mytest.C
B2.myPrint1();  // 输出:子类C_1
// B2.printB();  // 报错(java.lang.Error: Unresolved compilation problem)
// B2.printC();  // 报错(java.lang.Error: Unresolved compilation problem)

6 隔代继承

当直接父类和祖父类存在同名成员变量和成员方法时,采用就近原则,调用直接父类的。

D D1 = new D();
System.out.println(D1.a);  // 输出:1
D1.myPrint1();  // 输出:子类B_1
D1.myPrint2();  // 输出:父类_2

你可能感兴趣的:(实例用法)