精华内容
下载资源
问答
  • 向上转型

    2019-07-09 11:34:28
    我们在写继承的时候,经常会用到向上转型。那么在创建对象的时候,向上转型会调用谁的方法或变量呢,看下面的例子 package cn.com; class BaseClass{ public int book = 6; public void base(){ System.out....

    为什么要用向上转型?因为为了让方法复用,只写一个以父类为形参的方法即可。但是会丢失子类的特有方法

    向下转型是强转,可使用instance判断,用来调用子类的特有方法。

    class Animal {
        public void move() {
            System.out.println("动物可以移动");
        }
    }
    
    class Dog extends Animal {
        @Override
        public void move() {
            System.out.println("狗可以跑和走");
        }
        public void bark() {
            System.out.println("狗可以吠叫");
        }
    }
    
    class TestDog {
    //  形参类型只写一种Animal即可,如果没有向上转型,要写Dog,Fish,Cat等多种形参,那就累死了。
        public static void doEat(Animal h) {
            h.move();
        }
        public static void main(String args[]) {
            Animal a = new Animal(); // Animal 对象
    // 下一行就是向上转型,需要Animal,给个Dog,也行吧,但是不能执行Dog类的特有方法了。
            Animal b = new Dog(); 
    // 下一行需要Dog,给它Animal,肯定不行,编译出错!
    //        Dog d =new Animal();  
            Dog c = new Dog();
            a.move();// 执行 Animal 类的方法
            b.move();//执行 Dog 类的方法
    //        b.bark()  该方法使用失败
            c.bark();
    //下两行体现了向上转型的精髓,假如没有向上转型,面对不同的实参,形参要写很多种,那样该方法要写多少个呀!!!!
            doEat(new Dog()); //狗可以跑和走
            doEat(new Animal()); //动物可以移动
        }
    }

    但是向上转型丢失了子类特有的方法,这个就需要向下转型来弥补了。

    向下转型参考文献:https://www.cnblogs.com/lifexy/p/10812841.html

    -----------------------------------------------------------------------------------------------------------------------------

    以下为入门知识,可不看。

    package cn.com;
    class BaseClass{
        public int book = 6;
        public void base(){
            System.out.println("父类的普通方法");
        }
        public void test(){
            System.out.println("父类被覆盖的方法");
        }
    }
    
    public class SubClass extends BaseClass {
        public String book = "java基础书";
        public void test(){
            System.out.println("子类覆盖父类的方法");
        }
        public void sub(){
            System.out.println("子类的普通方法");
        }
    
        public static void main(String[] args) {
            BaseClass abc = new SubClass();
            System.out.println(abc.book);
            abc.test();
            abc.base();
    //      执行下面这一句会报错
    //      abc.sub();
        }
    }
    

    输出结果:

    6
    子类覆盖父类的方法
    父类的普通方法

    得到结论。向上转型,是子类继承父类,并创建对象的过程。语法为“父类 对象名 = new 子类构造器”,如  父 对象 = new 子类();

    子类继承后,只能调用父类中已有的方法,不能调用子类独特的方法。如果子类中已重写,则调用重写的方法。

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

    目录

     

    普通类示例

    抽象类的向上转型,

    接口向上转型:

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


     

    普通类示例

    父类:

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

     

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

     

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

    展开全文
  • 向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口向下转型:父类引用的对象转换为子类类型称为向下转型。前者是一个向上转型,Animal dog 引用...

    转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。

    向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口

    向下转型:父类引用的对象转换为子类类型称为向下转型。

    前者是一个向上转型,Animal dog 引用指向new Dog();子类对象当成父类对象,只能调用父类的成员,如果子类重写了父类的方法就根据这个引用指向调用子类重写的这个方法(这个方法就是覆盖override)。这个调用过程就称为“动态绑定”。

    转型需要注意的问题:

    向上转型时,父类指向子类引用对象会遗失除与父类对象共有的其他方法,也就是在转型过程中,子类的新有的方法都会遗失掉,在编译时,系统会提供找不到方法的错误。实例如下:

    public class Animal {

    public void eat(){

    System.out.println("animal eatting...");

    }

    }

    class Bird extends Animal{

    public void eat(){

    System.out.println("bird eatting...");

    }

    public void fly(){

    System.out.println("bird flying...");

    }

    }

    class Main{

    public static void main(String[] args) {

    Animal b=new Bird(); //向上转型

    b.eat();

    b.fly();  //此处提示在Animal中没有定义fly方法。

    在向下转型过程中,分为两种情况:

    情况一:如果父类引用的对象如果引用的是指向的子类对象,那么在向下转型的过程中是安全的。也就是编译是不会出错误的。

    情况二:如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。它可以使用instanceof来避免出错此类错误。实例如下:

    public class Girl {

    public void smile(){

    System.out.println("girl smile()...");

    }

    }

    class MMGirl extends Girl{

    @Override

    public void smile() {

    System.out.println("MMirl smile sounds sweet...");

    }

    public void c(){

    System.out.println("MMirl c()...");

    }

    }

    class main{

    public static void main(String[] args) {

    Girl g1=new MMGirl(); //向上转型

    g1.smile();

    MMGirl mmg=(MMGirl)g1;    //向下转型,编译和运行皆不会出错

    mmg.smile();

    mmg.c();

    Girl g2=new Girl();

    //MMGirl mmg1=(MMGirl)g2; //不安全的向下转型,编译无错但会运行会出错

    //mmg1.smile();

    //mmg1.c();

    if(g2 instanceof MMGirl){

    MMGirl mmg1=(MMGirl)g2;

    mmg1.smile();

    mmg1.c();

    }

    }

    总结:

    1、父类引用可以指向子类对象,子类引用不能指向父类对象。

    2、把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转型。

    如Father father = new Son();

    3、把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转型。

    如father就是一个指向子类对象的父类引用,把father赋给子类引用son 即Son son =(Son)father;

    其中father前面的(Son)必须添加,进行强制转换。

    4、upcasting 会丢失子类特有的方法,但是子类overriding 父类的方法,子类方法有效

    5、向上转型的作用,减少重复代码,父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。体现了JAVA的抽象编程思想。

    本文转载自:https://www.cnblogs.com/fickleness/archive/2013/06/21/3149011.html

    展开全文
  • 向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口向下转型:父类引用的对象转换为子类类型称为向下转型。前者是一个向上转型,Animal dog 引用...

    转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。

    向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口

    向下转型:父类引用的对象转换为子类类型称为向下转型。

    前者是一个向上转型,Animal dog 引用指向new Dog();子类对象当成父类对象,只能调用父类的成员,如果子类重写了父类的方法就根据这个引用指向调用子类重写的这个方法(这个方法就是覆盖override)。这个调用过程就称为“动态绑定”。

    转型需要注意的问题:

    向上转型时,父类指向子类引用对象会遗失除与父类对象共有的其他方法,也就是在转型过程中,子类的新有的方法都会遗失掉,在编译时,系统会提供找不到方法的错误。实例如下:

    public class Animal {

    public void eat(){

    System.out.println("animal eatting...");

    }

    }

    class Bird extends Animal{

    public void eat(){

    System.out.println("bird eatting...");

    }

    public void fly(){

    System.out.println("bird flying...");

    }

    }

    class Main{

    public static void main(String[] args) {

    Animal b=new Bird(); //向上转型

    b.eat();

    b.fly();  //此处提示在Animal中没有定义fly方法。

    在向下转型过程中,分为两种情况:

    情况一:如果父类引用的对象如果引用的是指向的子类对象,那么在向下转型的过程中是安全的。也就是编译是不会出错误的。

    情况二:如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。它可以使用instanceof来避免出错此类错误。实例如下:

    public class Girl {

    public void smile(){

    System.out.println("girl smile()...");

    }

    }

    class MMGirl extends Girl{

    @Override

    public void smile() {

    System.out.println("MMirl smile sounds sweet...");

    }

    public void c(){

    System.out.println("MMirl c()...");

    }

    }

    class main{

    public static void main(String[] args) {

    Girl g1=new MMGirl(); //向上转型

    g1.smile();

    MMGirl mmg=(MMGirl)g1;    //向下转型,编译和运行皆不会出错

    mmg.smile();

    mmg.c();

    Girl g2=new Girl();

    //MMGirl mmg1=(MMGirl)g2; //不安全的向下转型,编译无错但会运行会出错

    //mmg1.smile();

    //mmg1.c();

    if(g2 instanceof MMGirl){

    MMGirl mmg1=(MMGirl)g2;

    mmg1.smile();

    mmg1.c();

    }

    }

    总结:

    1、父类引用可以指向子类对象,子类引用不能指向父类对象。

    2、把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转型。

    如Father father = new Son();

    3、把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转型。

    如father就是一个指向子类对象的父类引用,把father赋给子类引用son 即Son son =(Son)father;

    其中father前面的(Son)必须添加,进行强制转换。

    4、upcasting 会丢失子类特有的方法,但是子类overriding 父类的方法,子类方法有效

    5、向上转型的作用,减少重复代码,父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。体现了JAVA的抽象编程思想。

    展开全文
  • 一、向上转型简单的说向.上转型就是:将-一个子类类型的对象赋值给- -个父类类型的变量,基本的实现语法:父类类型变量=new 子 类类型();DEMO:向上转型发现了可以使用父类类型的变量调用子类覆写了父类的方法,但是为...
  • 从 2 个名词开始说起:向上转型(upcasting)、向下转型(downcasting)。举个例子:有2个类,Father 是父类,Son 类继承自 Father。第 1 个例子:Fatherf1=newSon();// 这就叫 upcasting (向上转型)// 现在 f1 引用指向...
  • java之向上转型

    2020-12-21 08:22:36
    向上转型经典案例向上转型向上转型应注意的问题向上转型的好处静态方法的调用 经典案例 public class Animal { public void eat(){ System.out.println("animal eatting..."); } } public class Cat extends ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,815
精华内容 2,726
关键字:

向上转型