多态性:中的向下转型,instanceof 操作符的使用
每博一文案
都说树叶不是一天变黄的,人心也不是一天变凉的,每一个现在的自己,其实都是过去的自己拼凑的。
如今我们的气质里都藏着过去走过的路,看过的书和爱过的人,曾经的好,曾经的话,曾经的眼泪和孝顺,其实一直都在,生生不息。
如今你所遇见的这个我,是被这个世界打磨过的我。正如张爱玲所说的:如果你认识从前的我,你就会
原谅现在的我呢。别人都说你变了,却没人关心你到底经历过什么。
如果我们没走过他人走过的路,经历过他人经历的事,或许真的不能懂他人的悲喜。
每个人都曾想过,要活得无忧无虑,可社会复杂,人心难测,逼的人不得不伪装将自己内心的感情藏得更深。
不敢轻易去爱,因为明白了这个迷茫的世界需要冷漠与对抗。
所以,如果你认识从前的我,也许就会理解我现在的伪装。如果你不认识从前的我,就请不要随意的随意的评判
我,因为你不知道我是怎么走到今天的往后余生。
愿你的每一次成熟都不必靠受伤才能懂得,也愿你傻傻的天真,有人会用心守。
—————— 一禅心灵庙语
文章目录
- 多态性:中的向下转型,instanceof 操作符的使用
- 每博一文案
- 1. 多态: 对象类型转换
- 2. instanceof 操作符的使用
- 3. 总结:
- 4. 最后:
1. 多态: 对象类型转换
基本数据类型的转换
- 自动类型转换: 小的数据类型可以自动转换成 大的数据类型
long lnum = 20; // 在Java当中整数值默认是 int 类型
double dnum = 12.0f; // 在Java当中小数默认是 double 类型
- 强制类型转换: 可以把大 的数据类型 强制转换 成 小的数据类型
int inum = int(200L); // L long 类型的后缀
float fnum = (float)12.0;
对于 Java多态 引用类型(对象) 的转换:
- 向上转型: 子类的类类型可以自动转换成 父类的类类型,被称为 向上转型,但更多是被称为 是 多态 。
Person person = new Student(); // 向上转型 或者 多态。
- 强制类型转换: 可以将父类的类类型 必须通过 强制类型的转换 为 子类 的类类型,这样就可以调用子类中特有的方法/属性了。
Person person = new Student(); // 多态
Student student = (Person)person; // 强制向下转型
我们使用多态(向上转换) 为了 父类类型以后,如果想要调用 子类中特有的属性和方法 怎么办 ???
可以将 父类类型 强制转换为 对应子类 类型,从而就可以调用 子类中特有的属性和方法了。
多态:向下强制转换
如下代码:
package blogs.blog1;
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Student();
//p1.ncee(); // 直接编译的是父类类型,是无法调用子类中特有的属性/方法的,编译报错
// 可以使用强制向下转型为对应 子类类型来调用其中的特有的属性/方法
Student s1 = (Student)p1;
System.out.println(s1.name); // 可以调用子类中特有的属性/方法
s1.ncee(); // 可以调用子类特有的方法
Person p2 = new Teacher();
Teacher t1 = (Teacher)p2;
System.out.println(t1.name);
t1.teach(); // 调用子类中特有的方法
}
}
class Person { // 父类
String name = "Person";
int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public void show() {
System.out.println("我是 Person");
}
}
class Student extends Person{ // 子类
int studentId;
String name = "Student";
@Override
public void show() {
System.out.println("我是 Student");
}
public void ncee() {
System.out.println("高考");
}
}
class Teacher extends Person{ // 子类
int teacherId;
String name = "Teacher";
@Override
public void show() {
System.out.println("我是 Teacher");
}
public void teach() {
System.out.println("教书育人");
}
}
通过强制向下转型,将父类转为 对应的子类的类型,从而就可以调用子类中特有的属性/方法了。
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Student();
//p1.ncee(); // 直接编译的是父类类型,是无法调用子类中特有的属性/方法的,编译报错
// 可以使用强制向下转型为对应 子类类型来调用其中的特有的属性/方法
Student s1 = (Student)p1;
System.out.println(s1.name); // 可以调用子类中特有的属性/方法
s1.ncee(); // 可以调用子类特有的方法
Person p2 = new Teacher();
Teacher t1 = (Teacher)p2;
System.out.println(t1.name);
t1.teach(); // 调用子类中特有的方法
}
}
注意的是:使用向下强制转换,存在一个问题:就是如果两个引用类型之间没有子父类继承关系/本身的实例关系 ,而是并列关系的话,编译可以通过,但是运行时,会报:java.lang.ClassCastException
类异常。
如下代码:
package blogs.blog1;
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Student();
Teacher t1 = (Teacher)p1; // 编译可以通过,但是运行时会出现异常:ClassCastException
}
}
class Person { // 父类
String name = "Person";
int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public void show() {
System.out.println("我是 Person");
}
}
class Student extends Person{ // 子类
int studentId;
String name = "Student";
@Override
public void show() {
System.out.println("我是 Student");
}
public void ncee() {
System.out.println("高考");
}
}
class Teacher extends Person{ // 子类
int teacherId;
String name = "Teacher";
@Override
public void show() {
System.out.println("我是 Teacher");
}
public void teach() {
System.out.println("教书育人");
}
}
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Student();
Teacher t1 = (Teacher)p1; // 编译可以通过,但是运行时会出现异常:ClassCastException
}
}
报错原因:
- 编译不会报错是因为:我们将一个父类 Person 类型 强制向下转型为 了 Teacher 其中的一个子类,骗过了编译器,说这个类型就是这个。
- 运行报错是因为:编译器运行的时候,发现你给我 强制转换 过来的p1类型,与我本身 Teacher 没有任何关系,既不是 继承关系,也不是本身类的实例化。而是和我并列的 Student 类型,这样处理不对,报错: java.lang.ClassCastException
编译通过,运行不通过
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Teacher();
Student s1 = (Student)p1; // 编译可以通过,但是运行时会出现异常:ClassCastException
}
}
报错原因:
和上面一样。
编译不通过,运行不通过
public class PersonTest{
public static void main(String[] args) {
Student s1 = new Teacher();
}
}
报错原因:
左边赋值的 Student 与 右边 new 的 Teacher() 二者之间,没有继承关系,是两个并列不同的类类型,是无法相互强制赋值的。
编译无法通过,就像
String s1 = 123; 一样两个类型不一致,无法赋值。
编译通过,运行通过
直接使用对应的 向下强制转换为对应的类 。
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Student();
Student s1 = (Student)p1;
s1.ncee(); // Student 特有的方法
Person p2 = new Teacher();
Teacher t1 = (Teacher)p2;
t1.teach(); // Teacher 特有的方法
}
}
2. instanceof 操作符的使用
对应上述 强制向下转型 出现的 ClassCastException
可以预先使用 instanceof
操作符 进行一个判断。
需要注意的是: instanceof
是操作符,不是方法,所以可以直接使用,不需要导入包。
X instanceof Y 判断 X 是否是 Y的实例对象,或者 X 是否是 Y 的子类。如果是子类/是实例对象,返回 true, 不是返回 false
如下代码:
package blogs.blog1;
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Student();
Person p2 = new Teacher();
System.out.println("p1 instanceof Student: "+ (p1 instanceof Student));
System.out.println("p1 instanceof Person: "+(p1 instanceof Person));
System.out.println("p1 instanceof Teacher: "+(p1 instanceof Teacher));
System.out.println("***************************");
System.out.println("p2 instanceof Teacher: "+(p2 instanceof Teacher));
System.out.println("p2 instanceof Person: "+(p2 instanceof Person));
System.out.println("p2 instanceof Student: "+(p2 instanceof Student));
}
}
class Person { // 父类
String name = "Person";
int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public void show() {
System.out.println("我是 Person");
}
}
class Student extends Person{ // 子类
int studentId;
String name = "Student";
@Override
public void show() {
System.out.println("我是 Student");
}
public void ncee() {
System.out.println("高考");
}
}
class Teacher extends Person{ // 子类
int teacherId;
String name = "Teacher";
@Override
public void show() {
System.out.println("我是 Teacher");
}
public void teach() {
System.out.println("教书育人");
}
}
重点代码:
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Student();
Person p2 = new Teacher();
// 判断 p1 是否是 Student 的实例对象/子类,是返回 true, 不是返回 false
System.out.println("p1 instanceof Student: "+ (p1 instanceof Student));
// 判断 p1 是否是 Person 的实例地下/子类,是返回 true, 不是返回 false
System.out.println("p1 instanceof Person: "+(p1 instanceof Person));
System.out.println("p1 instanceof Teacher: "+(p1 instanceof Teacher));
System.out.println("***************************");
System.out.println("p2 instanceof Teacher: "+(p2 instanceof Teacher));
System.out.println("p2 instanceof Person: "+(p2 instanceof Person));
System.out.println("p2 instanceof Student: "+(p2 instanceof Student));
}
}
举例使用 instanceof
进行一个预先的判断,再向下强制转换
public class PersonTest{
public static void main(String[] args) {
Person p1 = new Student(); // 向上转型,多态
if(p1 instanceof Student) { // 判断 p1 是否是 Student 的实例/子类,是true,强制向下转换
Student s1 = (Student)p1;
System.out.println(s1.studentId); // 子类特有的属性
s1.ncee(); // 子类特有的方法
}
System.out.println("*******************");
if(p1 instanceof Teacher) { // 判断 p1 是否是 Teacher 的实例/子类,是true,强制向下转换
Teacher t1 = (Teacher)p1;
System.out.println(t1.teacherId); // 子类特有的属性
t1.teach(); // 子类特有的方法
}
System.out.println("*******************");
if(p1 instanceof Person) { // 判断p1 是否是 Person 的实例/子类,是true,强制向下转换
Person person = (Person)p1;
person.show();
}
}
}
3. 总结:
- 向上转换,称为多态
- 多态中:想要调用子类中特有的属性/方法,可以强制向下转型 为对应的子类。
- 强制向下转型可能会出现:编译正常,运行异常:
java.lang.ClassCastException
类异常 - 可以预先使用
instanceof
预先判断再强制向下转型,防止:强制向下转型失败报错:java.lang.ClassCastException
类异常
4. 最后:
限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,江湖再见,后会有期!!!