java继承、子类和父类之间转换

本文探讨了Java中的继承特性,包括构造函数的继承规则——子类需显式调用父类构造函数,并详细阐述了成员函数的继承原理。重点指出,即使通过类型转换,对象的方法调用依然基于其实际的类类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、java继承

1、构造函数的继承

java构造函数不会继承,但子类可以利用super()显式调用父类中的构造函数。若子类中没有定义构造函数,子类会调用父类中无参构造函数,若此时父类中没有无参构造函数则会出错(父类若无任何构造函数,会隐式创建一个无参构造函数,若父类有无参或有参的构造函数,则不会隐式创建)。子类继承父类时,若父类有自己的有参构造函数而且没有无参构造函数,那么 子类的构造函数必须显式的调用父类的有参构造函数,且要写在第一行。

2、成员函数的继承

若子类对象中操作的函数是继承父类中的函数并没有重写,那么成员函数操作的成员变量则是父类中的成员变量。

package com.test;

public class CastTest {
	public static void main(String[] args) {
		MyPoint mp = new MyPoint(3,4);
		System.out.println(mp.length());
	}
}

class Point{
	int x,y;
	Point(){
		this(0,0);
	}
	Point(int x){
		this(x,0);
	}
	Point(int x,int y){
		this.x = x;
		this.y = y;				
	}
	double length(){
		return Math.sqrt(x*x+y*y);
	}
}
class MyPoint extends Point{
	int x,y;
	MyPoint(int x,int y){
		this.x = x;
		this.y = y;				
	}
}
结果为0.0,不为5.0。除非在MyPoint()中重写length()方法。


二、示例说明

方法的引用是运行时进行的。对象首次生成时所属的类类型将确定调用哪种方法,校正对象为上级类或赋值对象为上级类类型的变量并不会改变调用方法的来源。

package com.test;

public class CastTest {
	public static void main(String[] args) {
		MyPoint mp = new MyPoint(3,4);
		Point p = new Point(8,6);
		Point q = mp;
		q.x = 5;
		q.y = 12;

		System.out.println();
		System.out.println("mp = ("+mp.x+","+mp.y+")");
		System.out.println("p = ("+p.x+","+p.y+")");
		System.out.println("q = ("+q.x+","+q.y+")");
		System.out.println();
		System.out.println("(Point)mp = ("+((Point)mp).x+","+((Point)mp).y+")"); //Point q = mp;这一句使输出是q的结果
		//System.out.println("(MyPoint)p = ("+((MyPoint)p).x+","+((MyPoint)p).y+")"); //出错,java.lang.ClassCastException,类转换异常,只能由子类											    //赋值給父类,不可逆                               
		System.out.println("(MyPoint)q = ("+((MyPoint)q).x+","+((MyPoint)q).y+")");//没有错,q本来指向的就是MyPoint类型,输出是mp的结果
		System.out.println();
		System.out.println("mp.length() ="+mp.length());//(length函数修改前)调用的是mp父类的length()方法,所以用到的是q的成员变量。                                                               //(length函数修改后)调用的是mp的length()方法,所以用到的是mp的成员变量。
<span style="white-space:pre">		</span>System.out.println("p.length() ="+p.length());
<span style="white-space:pre">		</span>System.out.println("q.length() ="+q.length());//与mp.length()的输出相同,如上所说校正对象为上级类或赋值对象为上级类类型的变量并不会改变调 <span style="white-space:pre">								</span>//用方法的来源。System.out.println();
<span style="white-space:pre">		</span>System.out.println("((Point)mp).length() ="+((Point)mp).length());//(length函数修改前)调用的是q的成员变量
 <span style="white-space:pre">								</span>//(length函数修改后)调用的是mp的length()方法,所以用到的是mp的成员变量。
<span style="white-space:pre">		</span>System.out.println("((Point)p).length() ="+((Point)p).length());
<span style="white-space:pre">		</span>System.out.println("((MyPoint)q).length() ="+((MyPoint)q).length());//(length函数修改前)先转为mp又调用了super的length,所以还是q的成员变量
 <span style="white-space:pre">										</span>//(length函数修改后)调用的是mp的length()方法,所以用到的是mp的成员变量
}}
<pre name="code" class="java">class Point{
	int x,y;
	Point(){
		this(0,0);
	}
	Point(int x){
		this(x,0);
	}
	Point(int x,int y){
		this.x =  x;
		this.y = y;				
	}
	double length(){
		return Math.sqrt(x*x+y*y);
	}
}
class MyPoint extends Point{
	int x,y;
	MyPoint(int x,int y){
		this.x  = super.x = x;
		this.y  = super.y = y;				
	}
	double length(){		
		return super.length();
	}
}




</pre><p></p><pre>
结果:
q.length() =13.0
mp = (3,4)
p = (8,6)
q = (5,12)

(Point)mp = (5,12)
(MyPoint)q = (3,4)

mp.length() =13.0
p.length() =10.0
q.length() =13.0

((Point)mp).length() =13.0
((Point)p).length() =10.0
((MyPoint)q).length() =13.0

若子类中length()转为

double length(){
		return Math.sqrt(x*x+y*y);
	}

则结果为:
mp = (3,4)
p = (8,6)
q = (5,12)

(Point)mp = (5,12)
(MyPoint)q = (3,4)

mp.length() =5.0
p.length() =10.0
q.length() =5.0

((Point)mp).length() =5.0
((Point)p).length() =10.0
((MyPoint)q).length() =5.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值