Java上转型对象的定义、关键字final的使用

Java上转型对象的定义:(使用上转型对象时不能和父类对象混淆)

对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能(上转型对象相当于子类对象的一个 “简化” 版对象);

一、上转型对象的概述:

将子类对象的引用赋给父类的对象(也就是使用子类的构造方法创建引用,再赋给父类对象),那么这个父类的对象就是子类对象的上转型对象;

简单的说就是:父类对象 拥有了 子类对象 的 引用;

一般创建格式如下:  对象 ou 、ous 就是上转型对象了 ;

        //创建上转型对象方法1
        objectUpward ou = new objectUpward_Test();
        //创建上转型对象方法2
        objectUpward_Test out = new objectUpward_Test();
        objectUpward ous = out ;  

父类:objectUpward;子类:objectUpward_Test;

二、上转型对象的特点:

1、上转型对象不能操作 子类 新增的 成员变量和方法,这一点和 父类对象相同

2、上转型对象可以访问 子类 继承的 成员变量和方法,这一点和 父类对象相同,都是输出父类中成员变量的值和方法内容;

3、上转型对象可以访问 子类 重写(隐藏)的 成员变量,这一点和 父类对象相同,都是输出父类中成员变量的值;

4、上转型对象可以访问 子类 重写(隐藏)的 方法,这一点和 父类对象不相同,输出的是子类重写方法后的内容,而父类对象输出的是父类自己方法中的内容;

(父类对象指:在子类中用父类构造方法声明一个父类的对象)

如下代码↗:

//父类
public class objectUpward {
	//被子类继承的成员变量,声明并赋予初值
	int variableFa = 147; 
	//被子类重写的成员变量,声明并赋予初值
	int Fa = 258;
	//被子类继承的方法
	void methodFa(){
		System.out.println("上转型对象 ou 调用子类 继承的方法methodFa");
	}
	// 被子类重写的方法
	void Fa() {
		System.out.println("上转型对象 ou 操作子类 继承的方法Fa");
	}
}
//子类
public class objectUpward_Test extends objectUpward {
	
	int variableCh = 111; 
	//子类自己新增的方法,计算两个数的和
	void oneself(double x,double y){
		double sum = x+y;
		System.out.println("一般类自己新增的方法:sum的值= "+sum);
	}
	//子类操作重写父类的成员变量和方法;
	int Fa = 117450;
	void Fa() {
	//	System.out.println("重写父类的方法Fa:父类方法被隐藏了");
	System.out.println("上转型对象 ou 调用子类重写父类的方法Fa:父类方法被隐藏了");	
	}
	
	public static void main(String[] args) {
		
		//子类中创建上转型对象,在子类中调用
//上转型对象:将子类对象的引用赋给父类的对象(也就是使用子类的构造方法创建引用,赋给父类对象);
		//创建方法1
		objectUpward ou = new objectUpward_Test();
		//创建方法2
		objectUpward_Test out = new objectUpward_Test();
		objectUpward ous = out ;
		//分别输出这些对象的引用
		System.out.println("使用子类构造方法创建的上转型对象 ou,引用= "+ou);
		//引用相等,拥有的实体相等
		System.out.println("子类创建的对象 out,引用= "+out);		
		System.out.println("使用子类对象赋值引用创建的上转型对象 ous,引用= "+ous);
		//测试上转型对象 ou 的调用情况,效果等同于上转型对象 ous
		//上转型对象操作子类 新增的成员变量和方法;不可以操作;报错variableCh cannot be resolved or is not a field
	//	System.out.println("上转型对象操作子类新增的成员变量:variableCh的值= "+ou.variableCh);
	//	ou.oneself(121.121,11.11);  //报错The method oneself(double, double) is undefined for the type objectUpward
		//上转型对象操作被子类 继承的成员变量和方法;可以操作;
		System.out.println("上转型对象 ou 操作子类 继承的成员变量:variableFa的值= "+ou.variableFa);
		ou.methodFa();
		//上转型对象操作被子类 重写的成员变量;可以操作;输出的是父类中的成员变量
		System.out.println("上转型对象 ou 操作子类 重写的成员变量:Fa的值= "+ou.Fa);
		//上转型对象操作被子类 重写的方法;可以操作;输出的是子类重写后的方法内容
		ou.Fa();
	}
}

代码输出结果:

使用子类构造方法创建的上转型对象 ou,引用= Chapter_Five.objectUpward_Test@7852e922
子类创建的对象 out,引用= Chapter_Five.objectUpward_Test@4e25154f
使用子类对象赋值引用创建的上转型对象 ous,引用= Chapter_Five.objectUpward_Test@4e25154f
上转型对象 ou 操作子类 继承的成员变量:variableFa的值= 147
上转型对象 ou 调用子类 继承的方法methodFa
上转型对象 ou 操作子类 重写的成员变量:Fa的值= 258
上转型对象 ou 调用子类重写父类的方法Fa:父类方法被隐藏了

以上代码中,上转型对象 ou 调用了子类 重写的方法Fa,但是方法输出的内容不是 父类方法的内容,而是 子类重写后方法的内容,这一点就是和父类对象不相同的地方;


三、上转型对象需要注意的地方:

1、不要将父类创建的对象和子类对象的上转型对象混淆;

如下所示: 上转型对象 ous 与 父类对象 ou 是不一样的;

//创建上转型对象 ous
        objectUpward_Test out = new objectUpward_Test();
        objectUpward ous = out ;  

 //创建父类对象 ou
        objectUpward ou = new objectUpward();

父类:objectUpward;子类:objectUpward_Test;

2、可以将对象的上转型对象在强制转换成一个子类对象,转换后,该子类对象又具备了子类所有的属性和功能;

如下所示:

//创建上转型对象 ous
        objectUpward_Test out = new objectUpward_Test();
        objectUpward ous = out ;  

//将上转型对象 ous 转换成一个子类对象

objectUpward_Test OU = (objectUpward_Test) ou;

父类:objectUpward;子类:objectUpward_Test;

3、不可以将父类创建的对象引用赋值给子类声明的对象;不能和上转型对象的创建相反;

如下所示:

//通过子类构造方法,创建上转型对象 ous,正确的;
        objectUpward ous = new objectUpward_Test();

//不能将父类对象引用赋值给子类对象 ,错误的;

        objectUpward_Test out = new objectUpward();

//报错:Type mismatch: cannot convert from objectUpward to objectUpward_Test

父类:objectUpward;子类:objectUpward_Test;

4、如果子类重写了父类的静态方法,那么子类对象的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法;这个和父类对象调用方法是相同的,输出的都是父类方法中的内容,而不是子类重写后方法中的内容;

如下代码↗:

//父类
public class objectUpward {
	//父类 static 静态方法
	static void sFa(){
		System.out.println("上转型对象 ou 操作父类的static方法,输出父类的方法内容");
	}
}
//子类
public class objectUpward_Test extends objectUpward {
	
	//子类重写父类 static 静态方法
		static void sFa(){
System.out.println("我重写了父类的static方法,但是上转型对象不能调用重写后的static方法");
		}
		
	public static void main(String[] args) {
		
		//如果子类重写了父类的静态方法,那么子类对象的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法;
		//上转型对象 ou 调用父类static方法,输出的是父类中方法的内容,而不是子类重写后方法中的内容;
                objectUpward ou = new objectUpward_Test();
		ou.sFa();
		//而子类重写后的父类static方法,需要通过子类对象进行调用
		objectUpward_Test oux = new objectUpward_Test();
		oux.sFa();
	}
}

代码输出结果:

上转型对象 ou 操作父类的static方法,输出父类的方法内容
我重写了父类的static方法,但是上转型对象不能调用重写后的static方法


关键字final的使用

final关键字可以修饰 类、成员变量、方法和方法中的局部变量 ;

1、当 final 修饰类时,则这个类就不能被继承,即这个类没有子类;

一般格式如下: 则类 A 是不能被其他类继承的;

final class A{
....
}

2、当 final 修饰方法时,则这个方法不能被子类重写,子类只能继承这个方法,不能对方法进行修改;

3、当 final 修饰某个成员变量或方法中的局部变量时,那它是一个常量,在程序运行时,常量的值是不能发生变化的;

4、当用 final 声明一个成员变量时,该成员变量必须要有初始值;

5、当用 final 声明一个局部变量时,该局部变量可以没有初始值,但是调用该值时,必须要有初始值才能进行调用;

如下代码所示;

//父类
public class finalKeyword {

	//声明父类一般方法
	void methodFa(){
		System.out.println("我是父类一般方法,子类可以进行重写");
	}
	
	//声明父类 final 方法
	final void methodFi(){
		System.out.println("我是父类final方法,子类不能进行重写");
	}
}
//子类
public  class finalKeyword_Test extends finalKeyword {

	// final关键字可以修饰 类、成员变量、和方法中的局部变量 ;
	//final int Nots;  //报错,final类型的成员变量,声明时必须要赋予初始值
	
	void Methods(final int x,int y){
		final int Not;  //final类型的局部变量可以先不赋予初始值,但是不能进行使用
		final int sum = x + y ; //x常量可以进行调用,因为被赋予了初始值

	//	System.out.println("final修饰的Not,无初始值,不能进行调用="+Not); 
        // 报错:The local variable Not may not have been initialized
		System.out.println("final修饰的sum="+sum);
	}
	
	//重写父类一般方法
	void methodFa(){
		System.out.println("我重写了父类的methodFa方法");
	}

	//父类的final方法不能进行重写
//	void methodFi(){
//		//错误:Cannot override the final method from finalKeyword
//	}
	
	public static void main(String[] args) {
		finalKeyword_Test fkt = new finalKeyword_Test();
		fkt.Methods(111,11);
		fkt.methodFa();
		fkt.methodFi();
	}
}

代码输出结果:

final修饰的sum=122
我重写了父类的methodFa方法
我是父类final方法,子类不能进行重写


 

发布了57 篇原创文章 · 获赞 10 · 访问量 7536

猜你喜欢

转载自blog.csdn.net/LagerSwan/article/details/104284335