参考http://devx.javaeye.com/blog/60005 本文面向Java初学者,我们在教材上经常会看到Java是多态的,可是一般的教科书只停留在理论上,很少有实际操作。现在把多态个概念用代码简单描述一下,由于本人水平有限,所以难免有不足之处。 首先我们有这样几个类,电脑,个人电脑,笔记本电脑。java 代码 class Computer{
public void turnOn(){ } } 现在有了电脑这个类,那么个人PC,笔记本都是继承他。java 代码 class PC extends Computer{ public void turnOn(){ System.out.println("PC has turn on"); } }
class NB extends Computer{ public void turnOn(){ System.out.println("NB has turn on"); } } 我们看到,每个类都有一个 turnOn()方法,而在父类中这个方法是空的,子类中各自有不同的实现,到这里可能还不太明显。如果有另外一个方法,要接受这些类作为参数,就像这样java 代码 class Test{ public void go(Computer computer){ computer.turnOn(); } } 这个方法接收的是基类参数,当然我们是可以把子类传递给方法的,也应该这么做。java 代码 go(new PC()); go(new NB()); 这样他就会去调用具体子类的turnOn()方法,所以这两次调用的输出是不一样的.如果不用基类作为参数,我们想调用每个子类的turnOn()方法,那么就要些两个方法体一样的go()而接收不同的参数的重载。java 代码 public void go(PC computer){ computer.turnOn(); }
public void go(NB computer){ computer.turnOn(); } 这样些也是正确的,但是这样会产生很多重复代码,而且也不易维护,当然这只是多态中最基本的一个部分,Java多态机制还有很多特性,关于这些建议大家看看 java编程思想(think in java)这本书,里面讲的很详细,这里只是很简单的描述了一下,还望个各位高手不要见笑。
多态:实现同一个接口,使用不同的实例而执行不同的操作.. 在运行时,根据实际创建的对象类型动态决定使用哪个方法. 如何实现多态? 1.子类重写父类的方法(或者是实现类实现接口的方法) 2.把父类类型(接口类型)的引用作为形参,把父类或子类(实现类)对象作为实参传入.那么这样会有什么好处呢? 给个例子//因为父类里面不知道要画什么东西,所以这里把draw()定义成抽象的更为合理 abstract class Shape { public abstract void draw(); }class Circle extends Shape { public void draw() { System.out.println("绘制圆形"); } }class Square extends Shape { public void draw() { System.out.println("绘制正方形"); } }class Trina extends Shape { public void draw() { System.out.println("绘制三角形"); } }class Test { public void f(Shape shape) { shape.draw();//这里父类类型引用调用draw();编译时无法知道是哪个实例的draw } public static void main(String[] args) { Test test=new Test(); test.f(new Circle());//运行时,会根据实际参数类型去动态绑定相应版本的f(); } }与动态绑定相对应的称呼为静态绑定,也许有些人不这么叫. 静态绑定就是编译时就已经知道要调用哪个版本的方法了..例如方法重载,,编译时就已经会根据参数列表去找相应的方法了 还有private final static 这三个关键字修饰的方法是静态绑定.无法产生动态绑定的 因为private是私有,一旦调用就肯定知道是哪个版本 .. final方法不能被重写,所以不存在动态绑定, static方法是属于类,而不属于实例,而且子类无法重写父类的static方法,只能隐藏! 所以无法产生多态.!
父类引用指向子类对象! 一看到这个情况必然多态! 举例子: class Animal { void call() { System.out.println("动物叫"); } } class Cat extends Animal{ void call() { System.out.println("猫叫"); } } class Dog extends Animal { void call() { System.out.println("狗叫"); } } class Girl { /* 这个方法里的参数就是多态,(红色字体)父类引用指向子类对象, 因为在你写这个方法时,也不知道会传什么对象进去所以 就把所有对象的父类写进去来实现多态,这样一来传进拿个子类 就调用哪个子类的方法 */ void myAnimalcall(Animal tom) { tom.call(); } } public class Animalcall { public static void main (String [] args) { //有个叫lily的女孩 Girl lily = new Girl(); //她养了个小狗 Dog dog = new Dog(); //现在要让我的狗用它自己的叫声叫 lily.myAnimalcall(dog);
} }
我学的时候有这样一个例子,不是程序是语言描述,可以帮助你理解一下。 一个人从小就没见过狗,一次他去动物园看见一只狗,他就问带她去的人,这是什么动物。(在不认识够的情况下他说动物,为什么?因为在以前他看见过其他区许多其他动物,所以在他的思想里有了动物这个类。)在没有任何他说这是狗的情况下,他也会和这个动物玩,是按所有动物都具有的方法和动物玩,(狗很听话)。狗仔接到命令时会按自己的方法执行这个人所下的命令。但是这个人不可能知道狗独有的方法,因为他只知道这是个动物。我下面写一个代码。你看看就是这个故事的! class Animal{ public void eat(){ System.out.println("animal eat"); } public void sleep(){ System.out.println("sleep 8 hours"); } } class Dog extendx Animal{ public void eat(){ System.out.println("dog eat"); } public void sleep(){ System.out.println("sleep 4 hours"); } } public class Happy{ public static void main(String[] args){ Animal a = new Dog(); a.sleep; } } 这样就是现实sleep 4 hours
Animal animal=new Bird();现在这种现象就实现了多态 其实那就是一种抽象 把子类都按父类的眼光来看待了 那么子类当然都是动物了 在抽象类和接口随处可以见到多态 也只能这么用 这样也方便 代码也实现了复用 而且很规范 更重要的是规范
本文面向Java初学者,我们在教材上经常会看到Java是多态的,可是一般的教科书只停留在理论上,很少有实际操作。现在把多态个概念用代码简单描述一下,由于本人水平有限,所以难免有不足之处。 首先我们有这样几个类,电脑,个人电脑,笔记本电脑。java 代码
class Computer{
public void turnOn(){
}
}
现在有了电脑这个类,那么个人PC,笔记本都是继承他。java 代码
class PC extends Computer{
public void turnOn(){
System.out.println("PC has turn on");
}
}
class NB extends Computer{
public void turnOn(){
System.out.println("NB has turn on");
}
}
我们看到,每个类都有一个 turnOn()方法,而在父类中这个方法是空的,子类中各自有不同的实现,到这里可能还不太明显。如果有另外一个方法,要接受这些类作为参数,就像这样java 代码
class Test{
public void go(Computer computer){
computer.turnOn();
}
}
这个方法接收的是基类参数,当然我们是可以把子类传递给方法的,也应该这么做。java 代码
go(new PC());
go(new NB());
这样他就会去调用具体子类的turnOn()方法,所以这两次调用的输出是不一样的.如果不用基类作为参数,我们想调用每个子类的turnOn()方法,那么就要些两个方法体一样的go()而接收不同的参数的重载。java 代码
public void go(PC computer){
computer.turnOn();
}
public void go(NB computer){
computer.turnOn();
}
这样些也是正确的,但是这样会产生很多重复代码,而且也不易维护,当然这只是多态中最基本的一个部分,Java多态机制还有很多特性,关于这些建议大家看看 java编程思想(think in java)这本书,里面讲的很详细,这里只是很简单的描述了一下,还望个各位高手不要见笑。
在运行时,根据实际创建的对象类型动态决定使用哪个方法.
如何实现多态? 1.子类重写父类的方法(或者是实现类实现接口的方法) 2.把父类类型(接口类型)的引用作为形参,把父类或子类(实现类)对象作为实参传入.那么这样会有什么好处呢? 给个例子//因为父类里面不知道要画什么东西,所以这里把draw()定义成抽象的更为合理
abstract class Shape
{
public abstract void draw();
}class Circle extends Shape
{
public void draw()
{
System.out.println("绘制圆形");
}
}class Square extends Shape
{
public void draw()
{
System.out.println("绘制正方形");
}
}class Trina extends Shape
{
public void draw()
{
System.out.println("绘制三角形");
}
}class Test
{
public void f(Shape shape)
{
shape.draw();//这里父类类型引用调用draw();编译时无法知道是哪个实例的draw
} public static void main(String[] args)
{
Test test=new Test();
test.f(new Circle());//运行时,会根据实际参数类型去动态绑定相应版本的f();
}
}与动态绑定相对应的称呼为静态绑定,也许有些人不这么叫.
静态绑定就是编译时就已经知道要调用哪个版本的方法了..例如方法重载,,编译时就已经会根据参数列表去找相应的方法了
还有private final static 这三个关键字修饰的方法是静态绑定.无法产生动态绑定的 因为private是私有,一旦调用就肯定知道是哪个版本 .. final方法不能被重写,所以不存在动态绑定, static方法是属于类,而不属于实例,而且子类无法重写父类的static方法,只能隐藏! 所以无法产生多态.!
一看到这个情况必然多态!
举例子:
class Animal {
void call() {
System.out.println("动物叫");
}
}
class Cat extends Animal{
void call() {
System.out.println("猫叫");
}
}
class Dog extends Animal {
void call() {
System.out.println("狗叫");
}
}
class Girl {
/*
这个方法里的参数就是多态,(红色字体)父类引用指向子类对象,
因为在你写这个方法时,也不知道会传什么对象进去所以
就把所有对象的父类写进去来实现多态,这样一来传进拿个子类
就调用哪个子类的方法
*/
void myAnimalcall(Animal tom) {
tom.call();
}
}
public class Animalcall {
public static void main (String [] args) {
//有个叫lily的女孩
Girl lily = new Girl();
//她养了个小狗
Dog dog = new Dog();
//现在要让我的狗用它自己的叫声叫
lily.myAnimalcall(dog);
}
}
一个人从小就没见过狗,一次他去动物园看见一只狗,他就问带她去的人,这是什么动物。(在不认识够的情况下他说动物,为什么?因为在以前他看见过其他区许多其他动物,所以在他的思想里有了动物这个类。)在没有任何他说这是狗的情况下,他也会和这个动物玩,是按所有动物都具有的方法和动物玩,(狗很听话)。狗仔接到命令时会按自己的方法执行这个人所下的命令。但是这个人不可能知道狗独有的方法,因为他只知道这是个动物。我下面写一个代码。你看看就是这个故事的!
class Animal{
public void eat(){
System.out.println("animal eat");
}
public void sleep(){
System.out.println("sleep 8 hours");
}
}
class Dog extendx Animal{
public void eat(){
System.out.println("dog eat");
}
public void sleep(){
System.out.println("sleep 4 hours");
}
}
public class Happy{
public static void main(String[] args){
Animal a = new Dog();
a.sleep;
}
}
这样就是现实sleep 4 hours