精华内容
参与话题
问答
  • 向上转型

    2015-06-03 22:21:29
    把子类对象赋给父类引用变量时,被称为向上转型。这种转型只是表明这个引用变量的编译时类型是父类,但实际执行它的方法时,依然表现出子类对象的行为方式。 把一个父类对象赋给子类引用变量时,就需要进行强制类型...

    把子类对象赋给父类引用变量时,被称为向上转型。这种转型只是表明这个引用变量的编译时类型是父类,但实际执行它的方法时,依然表现出子类对象的行为方式。

    把一个父类对象赋给子类引用变量时,就需要进行强制类型转换。即向下转型

    强制类型转换注意两点:

    1.引用类型之间转换必须具有继承关系

    2.数值型和布尔型不可转

     

    Animal  a = new Cat(); 向上转型,把猫转型为动物

    如果想要调用猫的特有方法,比如说抓老鼠,则需强制将父类引用转成子类类型。即向下转型

    Cat c  = (Cat)a;

    c.catchMouch();

    切记:向上转型后才能进行向下转型。 

     ”就像书的最后一页,只有先向前翻,才能向后翻“

     

    千万不要:将父类对象转成子类型。我们能转换的是父类引用指向了自己的子类对象时,该引用可以被提升,也可以被强制转换。

    多态自始至终都是子类对象在做变化

    Animal a = new Animal();

    Cat c = (Cat)a;

    展开全文
  • Java向上转型和向下转型

    千次阅读 多人点赞 2017-07-20 15:43:38
    Java向上转型和向下转型


    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/75530403冷血之心的博客)



    向上转型:父类引用指向子类对象                             向下转型:子类引用指向父类对象


    举例:Father是父类,Son是子类

    Father f1 = new Son();   // 这就叫 upcasting (向上转型), 现在f1引用指向一个Son对象

    Son s1 = (Son) f1;   // 这就叫 downcasting (向下转型),现在f1还是指向Son对象


    举例:Father是父类,Son是子类

    Father f2 = new Father();

    Son s2 = (Son) f2;       // 编译不出错,运行时出错(除非子类和父类拥有相同的属性和方法),子类引用不能指向父类对象


    向上转型:父类引用指向子类对象,将会丢失子类和父类中不一致的方法,并且父类引用调用的变量只能是父类中的。

    举例:

    class Person{
        private String name = "Person";
        int age=0;
        public void function() {
    		System.out.println("this is person");
    	}
    }
    public class Child extends Person{
    	
        public String grade;
        int age=10;
        public void function() {
    		System.out.println("this is child");
    	}
        public void b1(){
        	System.out.println("子类新方法");
        } //B类定义了自己的新方法
        @Test
        public  void test(){
            Person p = new Child();
            p.function();
            System.out.println(p.age);
        	
        }
    }

    此时将输出:

    “this is child”  

    0

    并且我们是不能使用p.b1()的,编译错误,因为,此时该对象p已经失去了该方法。


    向上转型的作用:

    这里以父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。

    public class Main{  
        
        public static void main(String[] args) {  
            dosleep(new Male());  
            dosleep(new Female());  
        }  
          
        public static void dosleep(Human h) {  
            h.sleep();  
        }  
    }  
    class Human {  
        public void sleep() {  
            System.out.println("Human sleep..");  
        }  
    }  
    class Male extends Human {  
        @Override  
        public void sleep() {  
            System.out.println("Male sleep..");  
        }  
    }  
    class Female extends Human {  
        @Override  
        public void sleep() {  
            System.out.println("Female sleep..");  
        }  
    }  

    如果dosleep以子类对象为参数,则有多少个子类就需要写多少个函数。这也体现了JAVA的抽象编程思想。




    如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,可以进群366533258一起交流学习哦~



    本群给大家提供一个学习交流的平台,内设菜鸟Java管理员一枚、精通算法的金牌讲师一枚、Android管理员一枚、蓝牙BlueTooth管理员一枚、Web前端管理一枚以及C#管理一枚。欢迎大家进来交流技术。



    展开全文
  • 类的向上转型: 父类(包括抽象类)创建的引用类型变量可以调用子类对象 父类引用类型变量应用子类对象时,调用方法只能调用父类中出现过的方法,如果方法被重写,调用的是子类中重写的方法。 普通类示例 父类:...

    目录

     

    普通类示例

    抽象类的向上转型,

    接口向上转型:

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


     

    普通类示例

    父类:

    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,参数类型都一样,只用写一个方法就行,极大的提高了代码的简洁性、适应性。

     

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

     

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

    展开全文

空空如也

1 2 3 4 5 ... 20
收藏数 5,742
精华内容 2,296
关键字:

向上转型