什么是上溯造型_Javajre下载[通俗易懂]

什么是上溯造型_Javajre下载[通俗易懂]Java上溯造型(upcasting)与下溯造型(Downcasting)上溯造型(upcasting)这个术语缘于继承关系图的传统画法:将基类至于顶部,而向下发展的就是派生类

什么是上溯造型_Javajre下载[通俗易懂]"

Java上溯造型(upcasting)与下溯造型(Downcasting)

上溯造型(upcasting)

这个术语缘于继承关系图的传统画法:将基类至于顶部,而向下发展的就是派生类。

文章使用的完整代码如下


public class Main { 
   
	public static void main(String[] args) { 
   
		Dog dog=new Dog();
		upcasting(dog);//汪汪汪。。。
		dog.tail();//摇尾巴...
		dog.speak();//汪汪汪。。。
		
		Animal animal=new Dog();
		animal.speak();//汪汪汪。。。
// animal.tail();//The method tail() is undefined for the type Animal
	
		
		//下溯
		Dog d =(Dog)animal;
		d.tail();
	
		//错误的下溯
// Animal a2=new Animal();
// Dog d2=(Dog)a2;
// d2.tail();
// 运行时报错:Exception in thread "main" java.lang.ClassCastException: class shangsu.Animal cannot be cast to class shangsu.Dog (shangsu.Animal and shangsu.Dog are in unnamed module of loader 'app')
// at shangsu.Main.main(Main.java:16) 
	}
	
    public static void upcasting(Animal animal){ 
     
        animal.speak();  
// animal.tail();//编译错误:The method tail() is undefined for the type Animal
        return;
    }  
    
}

 class Animal { 
   
	public void speak(){ 
   
// System.out.println("阿巴阿巴。。。");
	}
}
 
 
 class Dog extends Animal{ 
   
 
	@Override
	public void speak() { 
   
		System.out.println("汪汪汪。。。");
	}
	
	public void tail(){ 
   
		System.out.println("摇尾巴...");
	}
	
}

由于upcasting(Animal animal)方法的参数是 Animal类型的,因此如果传入的参数是Animal的子类,传入的参数就会被转换成父类Animal类型,这样你创建的 Dog对象 能使用的方法只是Animal中的签名方法;也就是说,在上溯的过程中,Dog的接口变窄了,它本身的一些方法(例如tail方法)就不可见

如果你 想使用Dog中存在而Animal中不存在的方法 (比如tail方法),编译时不能通过。由此可见,上溯造型是安全的类型转换。另一方面,虽然upcasting(Animal animal)方法的参数是 Animal类型,但传入的参数可以是 Animal的派生类 (这也是OO编程中惯用的编程方法),这里面就有个对象的类型识别问题,也就是运行时类型识别(run-time type identification,缩写为RTTI) 。RTTI的功能主要是由Class类实现的。

简单来说,上溯造型就是把子类向上转换为父类类型Animal animal=new Dog();,这样转型后只能使用父类中已经声明过的方法(叫)而不能通过转换后的父类调用子类特有的方法(摇尾巴)

下溯造型(Downcasting)

不一定安全,在编译时检测不到,运行时会抛出ClassCastException异常,对于测试来说,这样的错误也是很难检测的。

  • 将父类对象显示的转换成子类类型。
  • 曾经向上转换过的对象,才能再向下转换。对象不允许不经过上溯造型而直接下溯造型。
Animal animal=new Dog();
Dog d =(Dog)animal;
d.tail();

不正确的下溯示例:

Animal a2=new Animal();//动物类对象a2
Dog d2=(Dog)a2;//下溯为Dog类对象
d2.tail();
//编译时无错误

运行时报错Exception in thread "main" java.lang.ClassCastException: class shangsu.Animal cannot be cast to class shangsu.Dog (shangsu.Animal and shangsu.Dog are in unnamed module of loader 'app') at shangsu.Main.main(Main.java:16)

正确示例:

public static void downcasting(Animal animal){ 
   
	if(animal instanceof Dog){ 
   
		Dog dog=(Dog)animal;
		dog.speak();
		dog.tail();
	}
}
Java类中重写equals()用到的下溯造型

(2021.9.15更新)

Q:为什么要重写equals() ?

A:引用类型比较,要使用equals()方法,如果使用==比较,它比较的是两个引用类型的变量是否是同一个对象。

同时,调用List的contains() indexOf()方法 都需要实现equals()方法

对于自己创造的一个类,本身并没有重写equals()方法,如果需要比较两个类实例是否相等 就必须要重写(调用List的contains() indexOf()方法 也需要重写)

在廖雪峰老师的JAVA教程的一个练习中就有重写equals()的练习,在编写时,我发现这个就是下溯造型,于是在这里写出。

class Person { 
   
	String firstName;
	String lastName;
	int age;
public Person(String firstName, String lastName, int age) { 
   
	this.firstName = firstName;
	this.lastName = lastName;
	this.age = age;
}

/** * TODO: 覆写equals方法 */
@Override
public boolean equals(Object o) { 
   
	if(this == o) { 
   
		return true;
	}
	if(o instanceof Person) { 
   
		Person pp=(Person)o;
		if(this.firstName.equals(pp.firstName) && this.lastName.equals(pp.lastName) &&this.age==pp.age) { 
   
			return true;
		}
		
	}
	return false;
}

重写后即可完成main函数中的测试

public class Main { 
   
	public static void main(String[] args) { 
   
		List<Person> list = List.of(new Person("Xiao", "Ming", 18), new Person("Xiao", "Hong", 25),
				new Person("Bob", "Smith", 20));
		boolean exist = list.contains(new Person("Bob", "Smith", 20));
		System.out.println(exist ? "测试成功!" : "测试失败!");
	}
}

今天的文章什么是上溯造型_Javajre下载[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/86655.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注