目录
普通类示例
抽象类的向上转型,
接口向上转型:
作用:使用向上转型可以,提高代码的简洁性、灵活性、适用性。
普通类示例
父类:
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,参数类型都一样,只用写一个方法就行,极大的提高了代码的简洁性、适应性。
另外,这里向上转型是作为参数传递过去的,相应的,我们也可以作为返回值去写,同样可以极大的提高撸代码的效率。
个人所学和总结,如果那里不对,希望看到的大佬指正批评!