A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘茂林 高级黑马   /  2013-5-12 00:40  /  2066 人查看  /  9 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 刘茂林 于 2013-5-12 10:34 编辑

关于多态。不太明白,虽然知道是父类引用指向子类对象,但是没有更深刻的理解,求解惑,希望能让我搞明白。 最好能用个经典的小程序来说明这个问题,。多谢论坛的朋友啦。!

9 个回复

倒序浏览
本帖最后由 U芽Lady 于 2013-5-12 01:03 编辑

class 毕姥爷{
    void 讲课(){
        System.out.println("企业管理");
    }
    void 钓鱼(){
        System.out.println("钓鱼");
    }
}
class 毕老师 extends 毕姥爷{
    void 讲课(){
        System.out.println("JAVA");
    }
    void 看电影(){
        System.out.println("看电影");
    }
}
class {
    public static voidmain(String[] args) {
        毕姥爷 x = new 毕老师(); //毕老师对象被提升为了毕姥爷类型。
//      x.讲课();
//      x.看电影(); //错误.
        毕老师 y = (毕老师)x; //将毕姥爷类型强制转换成毕老师类型。
        y.看电影();//在多态中,自始自终都是子类对象在做着类型的变化。
    }
}

1,成员变量:在多态中,子父类成员变量同名。
        在编译时期:参考的是引用型变量所属的类中是否有调用的成员。(编译时不产生对象,只检查语法错误)
        运行时期:也是参考引用型变量所属的类中是否有调用的成员。
        简单一句话:无论编译和运行,成员变量参考的都是引用变量所属的类中的成员变量。
        再说的更容易记忆一些:成员变量 --- 编译运行都看 = 左边。
2,成员函数。
        编译时期:参考引用型变量所属的类中是否有调用的方法。
        运行事情:参考的是对象所属的类中是否有调用的方法。
        为什么是这样的呢?因为在子父类中,对于一模一样的成员函数,有一个特性:覆盖。
        简单一句:成员函数,编译看引用型变量所属的类,运行看对象所属的类。
        更简单:成员函数 --- 编译看 = 左边,运行看 = 右边。
3,静态函数。
        编译时期:参考的是引用型变量所属的类中是否有调用的成员。
        运行时期:也是参考引用型变量所属的类中是否有调用的成员。
        为什么是这样的呢?因为静态方法,其实不所属于对象,而是所属于该方法所在的类。
        调用静态的方法引用是哪个类的引用调用的就是哪个类中的静态方法。
        简单说:静态函数 --- 编译运行都看 = 左边。
回复 使用道具 举报
关于多态理解下面几点就行了.
1.如果没有多态会有什么样的结果?子类继承父类除了可以调用父类的方法外,还可以调用子类的特有方法.若有100个子类都继承了某个父类,如果他们都要使用父类的某个方法没有多态会出现什么情况,是不是这100个子类都要自己写这个方法,所以多态的出现后,子类可以直接调用父类的方法而不用再定义方法.
    调用方法: 父类型 类变量=new 子类对象,然后该子类对象,就能直接调用父类方法了.
2.再就是调用过程中该注意的问题了,如果父类没有改方法,子类就无法调用;如果子类父类都有该方法,子类会覆盖该方法,如果这方法只存在子类,用父类型变量调用子类方法会发生错误,因为父类没有该方法.
    大概就是这么多,关于多态论坛中有很多这方面的帖子的,可以自己搜索一下.
回复 使用道具 举报
本帖最后由 杨兴庭 于 2013-5-12 08:53 编辑

多态指同一个实体同时具有多种形式。在生活中多态指的是一个对象在不同环境在的不同状态和行为,例如同样是学生这个对象,但老师眼里的学生和家长眼里的学生是不同的,所以在java中需要多态来实现对象在不同环境下的不同形式。

多态:
多态具体指的是对象在不同状态下表现的形式
多态一般构造于继承和接口的环境下
多态体现在向上转型和向下转型(强制转型)
多态体现在代码上主要是:
父类  对象名=new 子类()
在方法上体现,声明方法的时候,形参为父类对象,方法调用时专递得实参是子类的对象
接口 对象=new 实现类
如果子类以父类的身份出现,子类自身特有的行为将会失效
如果子类以父类的身份出现,子类如果重写父类的方法,调用的是具体子类的方法(动态绑定)。
多态减少了方法重载之后的冗余,实现代码的可扩展性。


例题:编写一个Java应用程序,设计一个汽车类Vehicle,包含的成员属性有:车轮个数wheels和车重weight。小车类CarVehicle的子类,其中包含属性载人数passenger_load。卡车TruckVehicle的子类,其中包含载人数passenger_load和载重量payload。要求每个类都有相关数据的输出方法。编写测试类使用多态输出汽车的信息


/***
*父类
*/
public class Vehicle {

     /*声明属性*/
     private String name;
double wheels;
double weight;

/*getter,setter方法*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getWheels() {
return wheels;
}
public void setWheels(double wheels) {
this.wheels = wheels;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
/*构造方法*/
public Vehicle(String name, double wheels, double weight) {
super();
this.name = name;
this.wheels = wheels;
this.weight = weight;
}



/*实例方法*/
public void go(){

System.out.println(name+"有"+wheels+"轮子,"+"他的重量是:"+weight+"吨");

}
}
/**
**小汽车类,子类
*/
public class Car extends Vehicle {

public Car(String name, double wheels, double weight) {
super(name, wheels, weight);


}

@Override
public void go() {
super.go();
int passenger_load=5;
System.out.println("他能载"+passenger_load+"个人");




}



}


/**
*卡车类
*/
public class Truck extends Vehicle {

public Truck(String name, double wheels, double weight) {
super(name, wheels, weight);

}

@Override
public void go() {
super.go();
double passenger_load=6;
double payload=10;
System.out.println("他的载人量是:"+passenger_load+"\n"+"他的载重量是"+payload+"吨");

}



}



/*
*测试类
*/
public class test {

public void carry(Vehicle a)
{
a.go();
}


public static void main(String[] args) {

test get=new test();
get.carry(new Car("小汽车",4,5));

System.out.println("--------------------------");
get.carry(new Truck("大卡车",12,6));





}

}

评分

参与人数 1技术分 +1 收起 理由
刘胜寒 + 1

查看全部评分

回复 使用道具 举报
多态(polymorphism)
       一个对象变量可以指向多种实际类型的现象。

多态分两种:
①        编译时多态:编译时动态重载; Ainmal ainmal = new Dog();
②运行时多态:指一个对象可以具有多个类型。 ainmal.sleep();
对象是客观的,人对对象的认识是主观的。
例:
Animal a=new Dog();查看格式名称;(编译时看左边,运行时看右边)
Dog d=(Dog)a。声明父类来引用子类。(强制转换)
(思考上面的格式)
运行时多态的三原则:(应用时为覆盖)
1、        对象不变;(改变的是主观认识)
2、        对于对象的调用只能限于编译时类型的方法,如调用运行时类型方法报错。
在上面的例子中:Animal a=new Dog();对象a的编译时类型为Animal,运行时类型为dog。
注意:编译时类型一定要为运行时类型的父类(或者同类型)。
对于语句:Dog d=(Dog)a。将d强制声明为a类型,此时d为Dog(),此时d就可以调用运行时类型。注意:
a和d指向同一对象。属性看父类,方法看子类.
3、        在程序的运行时,动态类型判定。运行时调用运行时类型,即它调用覆盖后的方法。
关系运算符:instanceof
a  instanceof Animal;(这个式子的结果是一个布尔表达式)
a为对象变量,Animal是类名。
上面语句是判定a是否可以贴Animal标签。如果可以贴则返回true,否则返回false。
在上面的题目中: a instanceof Animal返回 True,
                 a instanceof Dog也返回 True,
instanceof用于判定是否将前面的对象变量赋值后边的类名。
Instanceof一般用于在强制类型转换之前判定变量是否可以强制转换。
如果Animal a=new Animal();
Dog d= (Dog)a;
此时编译无误,但运行则会报错。
Animal a=new Dog()相当于下面语句的功能:
Animal a=getAnimal();
Public static Animal.getAnimal(){
Return new Dog();
}
1、静态多态(方法重载)
2、动态多态(基于继承)---->引用多态

public class Animal{
        public void talk(){
                System.out.println("?????????");
        }
}
public class Cat extends Animal{
        public void talk(){System.out.println("miao miao");}
}

public class Dog extends Animal{
        public void talk(){System.out.println("wang wang");}
}
Animal an=new Cat();
an=new Dog();
在引用多态的场景中,一个引用变量能够做什么由类型决定,怎么做由对象决定
                Animal an=new Cat();


评分

参与人数 1技术分 +1 收起 理由
刘胜寒 + 1

查看全部评分

回复 使用道具 举报
关于多态的总结:
                *  多态就是指一个对象对应着多种类型,比如猫既是动物类,又是宠物类。
                *  多态在代码中的体现:父类或者接口的引用指向其子类的对象。
                *  多态时,各个成员怎样运行和反馈有如下特点:
                        成员变量(无论是否静态):编译和运行都参考等号的左边;
                        成员函数(非静态):编译看左边,运行看右边;
                        静态函数:编译和运行都看左边。
                下面是一个关于多态的基本实例,如果自己可以推出运行结果,那么关于多态的知识就掌握的差不多了。
  1. class Fu {
  2.         int num = 3;
  3.         void show() {
  4.                 System.out.println("fu show");
  5.         }
  6.         static void method() {
  7.                 System.out.println("fu static method");
  8.         }
  9. }

  10. class Zi extends Fu {
  11.         int num = 4;
  12.         void show() {
  13.                 System.out.println("zi show");
  14.         }
  15.         static void method() {
  16.                 System.out.println("zi static method");
  17.         }
  18. }

  19. class MyDuoTaiDemo2 {
  20.         public static void main(String[] args) {
  21.                 Fu.method(); // fu static method
  22.                 Zi.method(); // zi static method
  23.                 Fu f = new Zi();
  24.                 f.method(); // fu static method
  25.                 f.show(); // zi show
  26.                 System.out.println(f.num); // 3

  27.                 Zi z = new Zi();
  28.                 System.out.println(z.num); // 4
  29.         }
  30. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
刘胜寒 + 1

查看全部评分

回复 使用道具 举报
石贤芝 发表于 2013-5-12 09:35
关于多态的总结:
                *  多态就是指一个对象对应着多种类型,比如猫既是动物类,又是宠物类。
                *  多态在代 ...
  1. class Fu {
  2.     int num = 3;
  3.     Fu()
  4.     {
  5.       show();
  6.     }
  7.     void show() {
  8.             //System.out.println("fu show");
  9.             System.out.println("父类构造函数 ="+num);
  10.     }
  11.    
  12. }

  13. class Zi extends Fu {
  14.     String num = "xxx";
  15.     Zi()
  16.     {
  17.             show();
  18.     }
  19.     void show() {
  20.             System.out.println("zi show   "+num);
  21.     }
  22.    
  23. }

  24. class Test {
  25.     public static void main(String[] args) {
  26.          
  27.             Fu f = new Zi();
  28.         
  29.     }
  30. }
复制代码
把这个代码好好理解一下。。。 这个比较有代表性。
回复 使用道具 举报
问题如果以解决,请及时修改分类,否则继续提问问,谢谢合作!
回复 使用道具 举报
U芽Lady 发表于 2013-5-12 01:02
class 毕姥爷{    void 讲课(){        System.out.println("企业管理");    }    void 钓鱼(){        Sys ...

经典啊。。看了你这个例子我就明白了。。
回复 使用道具 举报
刘胜寒 发表于 2013-5-12 10:25
把这个代码好好理解一下。。。 这个比较有代表性。

谢谢。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马