java中有关多态的总结

来源:互联网 发布:mysql递归函数 编辑:程序博客网 时间:2024/05/18 02:39

  多态定义:

       多态是指具有继承关系的类层次结构可以定义同名的操作或属性,但这些属性或操作具有不同的含义,既具有不同的数据类型或表现出不同的行为。

可以传递多个IS-A测试的任何java对象都可以看作是多态的。

IS-A关系:

       OO中,IS-A的概念基于继承或接口实现,在继承树中,如果AB的下方,则可以说A IS-A BAB的一种),如果A实现了接口F,则可以说 A is-a F

多态包括实例方法的重写和实例方法的重载。

方法重写:方法重写依赖于继承(实现接口也可以)。

       重写规则:

1)  方法的变元列表必须完全相同。

2)  返回类型必须与超类方法的返回类型相同或其子类型相同。

3)  重写方法一定不能抛出比被重写方法声明的检验异常更或更广的检验异常。

4)  重写方法的访问级别一定不能比被重写方法的更严格。

方法的重载:

重载规则:重写方法必须改变变元列表。(返回类型、访问修饰符、声明的异常都可以改变)

有关引用变量几个要点:

1.       引用变量只能属于一种类型,一经声明就永远不能再改变。

2.       引用是一个变量,可以重新赋予其他对象。

3.       引用变量可以声明为类类型或是接口类型。

4.       引用变量可以引用与它类型相同的类型或它的任何子类型。

5.       引用对象决定了可以在该变量引用的对象上调用的方法,而对象类型决定了运行时使用哪个方法。

Egimport java.io.IOException;

 class Pa{

             public int i=1;

             public static void staticMeth()

             {

               System.out.println("Static-Pa");

             }

            public void meth()

            {

              System.out.println("Pa-meth-void");

            }

            protected void meth(int i)//重载,必须改变变元,访问修饰符可以改变

             {

                System.out.println("Pa-meth-void "+i);

             }

             public String meth(String s)throws IOException//改变返回类型,抛出更多异常

             {

               System.out.println("Pa-meth-String "+s);

              return null;

             }

     }

public class Sub extends Pa

{

    public int i=10;

    public static void staticMeth()  //静态方法不是重写,但是可以重新定义。

    {

       System.out.println("static-Sub");

    }

 

         public void meth()throws RuntimeException //可以抛出运行时异常

        {

              System.out.println("Sub-meth-void");

        }

 

        protected void meth(int i)     

 {

                System.out.println("Sub-meth-void "+i);

        }

        public String meth(String s)//重写方法可以比被重写方法返回更少的异常

        {

               System.out.println("Pa-meth-String "+s);

              return null;

        }

public static void main(String []args)

{

       Pa pa=new Pa();

        Sub sub=new Sub();

        Pa psub=new Sub();

        System.out.println(pa.i);//输出1

        System.out.println(sub.i);//输出10

        System.out.println(psub.i);//输出1

        pa.staticMeth();//Static-Pa

        sub.staticMeth();//Static-Sub

        psub.staticMeth();//Static-Pa

        //对于实例变量和静态方法不属于多态,他们只和引用类型有关

        psub.meth();//输出Sub-meth-void

 

        try

        {

           psub.meth("abc");//输出Pa-meth-String abc

        }

        catch(Exception e){}

       //引用对象决定了可以在该变量引用的对象上调用的方法,而对象类型决定运行时使用哪个方法,

       // 因为引用对象上为抛出异常的方法,所以要用try/catch

    } }

匿名内部类中调用自己创建的方法则会编译失败。

 

    eg: Class P{}

 

      Class Sub

 

      {

         P p=new P(){void newmethod(){}};
        p.newmethod();//此处错误。

      } 

//引用对象决定了可以在该变量引用的对象上调用的方法,而对象类型决定运行时使用哪个方法,

 

有关装箱拆箱和var-arg的多态的调用:

当方法重载调用的时候,首先看是否能找到精确匹配,如果能则调用能精确匹配的方法,如果没有则再进行“加宽”或var-arg的匹配方法。

即,加宽优于var-arg,加宽优于装箱执行。

Java的设计者认为:最重要的规则应该是已有代码应该像它们过去那样运行,因此既然加宽能力已经存在,加宽应该优于装箱。

                 Var-arg方法比其他方法“更宽松”,更像一个“捕获所有”的方法,应该将“捕获所有”的能力用作最后一种手段。

Eg

 public class Test

{

    public static void go(int x)

    {

       System.out.println("int");

    }

    public static void go(Byte x)

    {

       System.out.println("Byte");

    }

    public static void go(double d)

    {

       System.out.println("double");

    }

    public static void go(double... x)

    {

       System.out.println("double...");

    }

    public static void main(String[] args) {

       byte b=1;

       Byte byt=1;

       double d=3.4;

       go(b);

       go(byt);

       go(d);

       go(b,d);

    }

}

结果为:

   int

Byte

double

double...