java的多态
追问:
t.find(f);
t.find(m);
能不能说说find里面的f、m是怎么用的,我只知道实例t调用了find()方法,里面的就不懂了
追问:
t.find(f);
t.find(m);
能不能说说find里面的f、m是怎么用的,我只知道实例t调用了find()方法,里面的就不懂了
答案:关于java的多态,有的书上是这样讲的,它讲java的多态分成静态的多态,和动态的多态,而所谓静态的多态就是只函数的重载,动态的多态就是方法的覆写。
如下面:
class Test
{
void print()
{
System.out.println("hello world");
}
void print(int x)
{
System.out.println("hello world"+i);
}
public static void main(String []args)
{
Test ts=new Test();
ts.print();
ts.print(10);
}
}
/*
上面的程序就是在一个类中成员方法的重载例子。也就是一个静态的多态性。系统会在你编译的时候根据你调用的方法的参数列表来动态的决定调用那一个函数。
*/
动态的多态:
class Test
{
void print()
{
System.out.println("hello Test");
}
public static void main(String []args)
{
A a=new A();
a.print();
}
}
class A extends Test
{
void print()
{
System.out.println("hello A");
}
}
/*
这时由于子类覆写了父类的方法,所以调用的是子类覆写后的方法。
这是动态的多态。
*/
你上面的问题,是把一个子类的实例赋值给一个父类。这是可以的,其实我个人觉得这好像不是什么多态的问题。请看下面的程序:
class A
{
public static void main(String []args)
{
A [] a=new A[3];
a[0]=new B();
a[1]=new C();
a[2]=new D();
for(int i=0;i<a.length;i++)
{
a[i].print();
}
}
}
class B extends A
{
void print()
{
System.out.println("hello B");
}
}
class C extends A
{
void print()
{
System.out.println("hello C");
}
}
class D extends A
{
void print()
{
System.out.println("hello D");
}
}
/*
上面的程序执行的结果:
hello B
hello C
hello D
可以看出,程序不会调用父类的print()方法,再说父类根本就没有print()方法,但是它不会报错。这就是JVM (java虚拟机),能在程序运行时,动态的识别变量的类型。就像上面一样。这主要是考java的运行时的类型识别机制实现的,当然我认为这其实也可以看成是java多态的一种表现。
*/
在java中子类是父类的实例,这就像是说 鱼是动物。但不能说动物就一定是鱼,这也是符合了人们对现实世界的认识规律。另外java为我们提供了一个关键字,在孙鑫的教程里面也讲到了吧。它是instanceof
你可以用这来判断一个对象是否是一个类的实例。还是上面的A ,B,C ,D类的例子:
在mian函数中写上下面的代码:(把原来的代码删掉)
B b=new B();
if(b instanceof A)
System.out.println("b instanceof A");
//输出:b instanceof A
说明b是A类的实例。
再看下面的例子。
A a=new B();
if(a instanceof B)
System.out.println("a instanceof B");
//输出:a instanceof B
但此时不能这样,B b=a;
虽然a是B的实例但是这里不能这样赋值,要像下面:
B b=(B)a;
//进行类型的强制转换
关于这部分你还是自己体会吧。
2.关于你所说的函数的参数是对象的问题:
函数的参数当然可以是一个对象,类是我们自定义的类型,他可以像基本的数据类型(int ,float等)一样用来定义变量,在java中类用的是相当多的,类属于引用类型,而基本类型的变量属于值类型。在函数传递参数的过程中,实际上是传的是对象的地址。方法的重写和重载是Java多态性的不同表现。
重写是父类与子类之间多态性的一种表现。
重载是一个类中多态性的一种表现。
如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 。
子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载。
并且重载的方法是可以改变返回值的类型的。
应该能懂了吧
…………我给你解释下多态的意思
多态,我觉得它的作用就是用来将接口和实现分离开,改善代码的组织结构,增强代码的可读性。
以下是我对多态的小结
1. Java中除了static和final方法外,其他所有的方法都是运行时绑定的。在我另外一篇文章中说到private方法都被隐式指定为final 的,因此final的方法不会在运行时绑定。当在派生类中重写基类中static、final、或private方法时,实质上是创建了一个新的方法。
2.在派生类中,对于基类中的private方法,最好采用不同的名字。
3.包含抽象方法的类叫做抽象类。注意定义里面包含这样的意思,只要类中包含一个抽象方法,该类就是抽象类。抽象类在派生中就是作为基类的角色,为不同的子类提供通用的接口。
4.对象清理的顺序和创建的顺序相反,当然前提是自己想手动清理对象,因为大家都知道Java垃圾回收器。
5.在基类的构造方法中小心调用基类中被重写的方法,这里涉及到对象初始化顺序。
6.构造方法是被隐式声明为static方法。
7.用继承表达行为间的差异,用字段表达状态上的变化。
为了给你讲明白,我再给你写端例子
/**
* 定义一个基类
*/
public Class Parents {
public void print() {
System.out.println(“parents”);
/**
* 定义两个派生类
*/
public Class Father extends Parents {
public void print() {
System.out.println(“father”);
public Class Mother extends Parents {
public void print() {
System.out.println(“mother”);
/**
* 测试输出结果的类
*/
public Class Test {
public void find(Parents p) {
p.print();
public static void main(String[] args) {
Test t = new Test();
Father f = new Father();
Mother m = new Mother();
t.find(f);
t.find(m);
最后的输出结果分别是father和mother,将派生类的引用传给基类的引用,然后调用重写方法,基类的引用之所以能够找到应该调用那个派生类的方法,就是因为程序在运行时进行了绑定。java多态是java面向对象特征之一。可分为方法的重写和重载。所以想理解多态则要将重写和重载弄清楚。重写一般用在子类去实现父类的方法,重载一般在同一个类中使用。
我以前的一个简单例子:
class A{
void say(){
System.out.println("he said you are beautiful!");
}
}
class B extends A{
void say(){
System.out.println("she said you are handsome!");
}
void say(String words){
System.out.println("he said you are beautiful!"+words);
}
}
class Demo {
public static void main(String []args){
A a=new B();
a.say();
B b=new B();
b.say();
b.say(" And he love you very much!");
}
}B类中的say()和say(String words)2方法重载,A类中say()被B类重写。
子类继承父类,然后把子类当父类用,那就是多态