Java知识扫盲——向上转型(类向上转型、接口向上转型)以及向上转型的优势、灵活运用

目录

 

普通类示例

抽象类的向上转型,

接口向上转型:

作用:使用向上转型可以,提高代码的简洁性、灵活性、适用性。


 

普通类示例

父类:

package 普通类向上转型;

public class Father {
	public int age = 48;
	public void sayAge() {
		System.out.println("我的年龄是:"+age);
	}
	public void myDaughter() {
		System.out.println("我女儿18岁");
	}
}

子类:

package 普通类向上转型;

public class Daughter extends Father{
	public int age = 18;
	public String sex = "女";
	@Override
	public void sayAge() {
		System.out.println("我的年龄是:"+age);
	}
	
	public void saySex() {
		System.out.println("我的性别是:"+sex);
	}
}

测试类:

package 普通类向上转型;

public class Test {

	public static void main(String[] args) {
		System.out.println("------输出各自属性和方法------");
		Father father = new Father();
		System.out.println(father.age);
		father.sayAge();
		
		System.out.println("----------");
		
		Daughter daughter = new Daughter();
		System.out.println(daughter.age);
		daughter.sayAge();
		System.out.println(daughter.sex);
		daughter.saySex();
		
		System.out.println("------输出向上转型后的,属性和方法------");
		Father a = new Daughter();
		System.out.println(a.age);
		// a 没有了sex属性
		a.sayAge();
		// a 没有了saySex方法
		a.myDaughter();
	}

}

输出结果:

------输出各自属性和方法------
48
我的年龄是:48
----------
18
我的年龄是:18
女
我的性别是:女
------输出向上转型后的,属性和方法------
48
我的年龄是:18
我女儿18岁

总结:可以看出,子类向上转型后。

1. 属性和方法,父类有的才能保留,子类特有的属性和方法,都消失。——测试类中,a不能访问sex属性和saySex方法

2. 如果子类重写了父类的方法,就调用子类重写的方法。否则掉调用父类方法——测试类中,输出a.age,结果为48,说明a的属性指向父类属性,sayAge输出18,说明调用了子类方法。(因为子类中调用age变量,指向的是子类的age=18)

图示:

抽象类的向上转型,

与上边写法,结论都一样,不再详讲,放个代码,供大家看看:

父类(抽象类)

package 抽象类向上转型;

public abstract class Father {
	
	public int age = 48;
	
	public abstract void sayAge();
	
	public void myDaughter() {
		System.out.println("我女儿18岁");
	}
}

子类

package 抽象类向上转型;

public class Daughter extends Father{
	
	public int age = 18;
	public String sex = "女";
	@Override
	
	public void sayAge() {
		System.out.println("我的年龄是:"+age);
	}
	
	public void saySex() {
		System.out.println("我的性别是:"+sex);
	}

}

测试类:
 

package 抽象类向上转型;

public class Test {

	public static void main(String[] args) {
		System.out.println("------输出各自属性和方法------");
		System.out.println("抽象类不能直接实例化");
		
		System.out.println("----------");
		
		Daughter daughter = new Daughter();
		System.out.println(daughter.age);
		daughter.sayAge();
		System.out.println(daughter.sex);
		daughter.saySex();
		
		System.out.println("------输出向上转型后的,属性和方法------");
		Father a = new Daughter();
		System.out.println(a.age);
		// a 没有了sex属性
		a.sayAge();
		// a 没有了saySex方法
		a.myDaughter();
	}

}

输出结果:

------输出各自属性和方法------
抽象类不能直接实例化
----------
18
我的年龄是:18
女
我的性别是:女
------输出向上转型后的,属性和方法------
48
我的年龄是:18
我女儿18岁

接口向上转型:

接口:
 

package 接口向上转型;

public interface Father {
	
	int AGE = 48;
	
	public abstract void sayAge();
	
}

实现类:
 

package 接口向上转型;

public class Daughter implements Father{
	
	public int age = 18;
	public String sex = "女";
	
	@Override
	public void sayAge() {
		System.out.println("我的年龄是:"+age);
	}
	
	public void saySex() {
		System.out.println("我的性别是:"+sex);
	}

}

测试类:

package 接口向上转型;

public class Test {

	public static void main(String[] args) {
		System.out.println("------输出各自属性和方法------");
		System.out.println("抽象类不能直接实例化");
		
		System.out.println("----------");
		
		Daughter daughter = new Daughter();
		System.out.println(daughter.age);
		daughter.sayAge();
		System.out.println(daughter.sex);
		daughter.saySex();
		
		System.out.println("------输出向上转型后的,属性和方法------");
		Father a = new Daughter();
		System.out.println(a.AGE);
		// a 没有了sex属性
		a.sayAge();
		// a 没有了saySex方法
	}

}

总结:

1. 调用的方法一定是实现类的方法。——因为接口中不能出现普通方法(jdk1.8可以写,但不常用)。

2. 常量指向的是接口中的常量。——输出a.AGE结果是48。

作用:使用向上转型可以,提高代码的简洁性、灵活性、适用性。

话说有对比才会有伤害,咱们用向上转型和不用向上转型,做同一个工作试试。

假设我们要进行一项调查,随机抽取10个人,查看他的职业(咱们只写学生和老师两个职业)。

不使用向上转型:

学生:

package 向上转型的应用.做参数;

public class Student {

	public void work() {
		System.out.println("我是学生,我的工作是学习");
	}

}

老师:

package 向上转型的应用.做参数;

public class Teacher {

	public void work() {
		System.out.println("我是老师,我的工作是教学");
	}

}

测试类:

package 向上转型的应用.做参数;

public class Test {

	public static void main(String[] args) {

		// 模拟10次随机抽人
		for (int i = 0; i < 10; i++) {
			// 生成随机数,模拟随机抽人
			final double d = Math.random();
			final int j = (int)(d*10);
			if (j<5) {
				// 传递抽取的人
				sayHerJob(new Student());
			} else {
				// 传递抽取的人
				sayHerJob(new Teacher());
			}

		}

	}

	private static void sayHerJob(Student s) {
		s.work();
	}
	private static void sayHerJob(Teacher t) {
		t.work();
	}
}

运行结果:

我是老师,我的工作是教学
我是老师,我的工作是教学
我是老师,我的工作是教学
我是学生,我的工作是学习
我是学生,我的工作是学习
我是老师,我的工作是教学
我是老师,我的工作是教学
我是老师,我的工作是教学
我是学生,我的工作是学习
我是学生,我的工作是学习

可以看到,有两个职业sayHerJob方法就复写了一遍,如果世界上有1881种职业,你就复写1880次方法???

显然不可能,代码冗余,死板。

再来看看咱们的向上转型

我们可以看到学生和老师都是人,我们只问她们职业。

这句话是什么意思?约束——接口!

Person接口

package 向上转型的应用.做参数;

public interface Person {
	void work();
}

学生:

package 向上转型的应用.做参数;

public class Student implements Person {

	@Override
	public void work() {
		System.out.println("我是学生,我的工作是学习");
	}

}

老师

package 向上转型的应用.做参数;

public class Teacher implements Person {

	@Override
	public void work() {
		System.out.println("我是老师,我的工作是教学");
	}

}

测试:

package 向上转型的应用.做参数;

public class Test {

	public static void main(String[] args) {

		Person p = null;
		// 模拟10次随机抽人
		for (int i = 0; i < 10; i++) {
			// 生成随机数,模拟随机抽人
			final double d = Math.random();
			final int j = (int)(d*10);
			if (j<5) {
				// 向上转型
				p = new Student();
			} else {
				// 向上转型
				p = new Teacher();
			}

			// 传递抽取的人
			sayHerJob(p);
		}

	}

	private static void sayHerJob(Person p) {
		p.work();
	}
}

运行结果:

我是老师,我的工作是教学
我是老师,我的工作是教学
我是老师,我的工作是教学
我是老师,我的工作是教学
我是老师,我的工作是教学
我是老师,我的工作是教学
我是老师,我的工作是教学
我是老师,我的工作是教学
我是学生,我的工作是学习
我是老师,我的工作是教学

把学生和老师,都向上转型成Peron,参数类型都一样,只用写一个方法就行,极大的提高了代码的简洁性、适应性。

另外,这里向上转型是作为参数传递过去的,相应的,我们也可以作为返回值去写,同样可以极大的提高撸代码的效率。

个人所学和总结,如果那里不对,希望看到的大佬指正批评!

猜你喜欢

转载自blog.csdn.net/qq_42909053/article/details/106325632
今日推荐