黑马程序员_多态和内部类

一、多态

1多态的涵义

多态:可以理解为事物存在的多种体现形态

多态字面上的意思就是多种形态。在面向对象语言中,我们可以将函数的形参定义为一个父类类型,而在真正调用该函数时这个父类类型的所有子类对象都可以传入,根据传入的子类对象不同函数可以运行处多种形态。

简而言之:多态就是父类引用指向子类对象。  

人:男人,女人

  

动物:猫,狗

猫 x=new 猫(); 

动物x=new 猫();

 

1、多态的体现:

父类的引用只想了自己的子类对象

  

2、多态的前提:

必须是类与类之间有关系。要么继承,要么实现

通常还有一个前提:存在覆盖。

3、多态的好处:

提高程序的扩展性

 

4、多态的应用:

提高了扩展性,但是只能使用父类的引用访问父类中的成员。

 

public class duotai 

{

     public static void main(String[] args)

     {

     cat c=new cat();

     c.eat();

     

     dog d=new dog();

     d.eat();

     function(new dog());

     

     }

     public static void function(animal a)

     {

     a.eat();

    

     }

     

}

class cat extends animal

{

      public void eat()

     {

              System.out.println("吃鱼");

     }

     public void catchmouse()

    {

             System.out.println("抓老鼠");

    }

}

class dog extends animal

{

      public void eat()

      {

             System.out.println("吃骨头");

       }

       public void kanja()

      {

             System.out.println("看家");

      }

}

abstract class animal

{

        public abstract void eat();

}

在多态成员函数的特点;

在编译时期:

参阅引用型变量所属的类中是否有调用的方法,如果又,编译通过 如果灭有则编译失败

在运行时期:

参阅对象所属的类中是否有调用的放啊。

总结:多态成员函数时,编译看左边,运行看右边。

在多态成员变量时:

无论编译还是运行,都看左边

在多态中静态成员函数的特点:

无论编译和运行,都参考左边。静态方法是不需要对象的。

如下代码体现:

public class 特点

{

     public static void main(String[] args)

     {

     //zi z=new zi();

     //z.method1();

     //z.method2();

     //z.method3();

     

     fu f=new zi();

     //System.out.println(f.num);

     f.method4();

     

     zi z=new zi();

     z.method4();

    // System.out.println(z.num);  

     }

}

class fu

{

        int num=5;

        void method1()

        {

                   System.out.println("fu method");

        }

         void method2()

        {

                  System.out.println("fu method2");

        }

        static void method4()

        {

                  System.out.println("fu method4");

         }

}

class zi extends fu

{

        int num=8;

       void method1()

        {

                  System.out.println("zi method1");

         }

        void method3()

       {

                 System.out.println("zi method3");

        }

        static void method4()

        {

                 System.out.println("zi method4");

        }

}

转型

把一个子类当做父类来用的时候,不能调用子类特有方法。

因为编译时编译器会做语法检查,看到变量是父类类型那么就会到父类中查找是否有该方法,没有则报错。

这种情况下,就需要强制类型转换,将父类类型强转成子类类型。

以(子类名)变量名形式进行强制类型转换

强制类型转换时,无论类型是否匹配编译都不会报错,但如果类型不匹配运行会报错,我们可以使用instanceof进行判断,编译时预知错误。

在子类当做父类来用时,不能调用特有方法,如果一定要调用,就需要强制类型转换回子类。在做转换时最好instanceof判断一下类型是否匹配。

public class trans

{

     public static void main(String[] args)

     {

     animal a=new cat();//类型提升,向上转型。

     a.eat();

     ((cat) a).catchmouse();

     

     //如果想要调用猫的特有方法是,如何操作

     //强制将父类的   引用,转成子类类型。 

     cat c=(cat)a;//向下转型

     c.catchmouse();

     }

}

二、内部类(InnerClass)

1类中的内部类

在类里面定义的类称之为内部类(Inner Class),内部类是外部类的一个成员。

内部类必须创建外部类对象才能使用。

创建内部类对象时必须先创建一个外部类对象,通过一个外部类对象才能创建内部类对象。

外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

内部类可以直接访问外部类的成员,而外部类不能直接访问内部类的成员。访问方式:外部类名.this.成员名

内部类可以访问外部类成员,因为在使用内部类时一定会有外部类对象,且只对应一个。

外部类不能访问内部类成员,因为在使用外部类时有可能还没有创建内部类对象。

如果一定要在外部类中使用内部类成员,那么需要创建内部类对象,通过对象来访问。

内部类中不能定义静态成员。

因为内部类需要创建外部类对象才能使用,static的本意是不创建对象就能使用,这是矛盾的。

内部类的class文件名为:外部类名.内部类名.class

2局部内部类

内部类定义在局部时:

(1)不可以被成员修饰符修饰

(2)可以直接访问外部类中的成员,因为持有外部类中的引用

但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量

public class innerclass

{

             public static void main(String[] args)

            {

                          new oute().method(7);//进栈后出栈了,

                          new oute().method(8);

             }

}

class oute

{

            int x=3;

            void method(final int a)

           {

                        final int y=4;

                        class inner

                        {

                                    void funtion()

                                     {

                                                 System.out.println(a);

                                     }

                         }

                         new inner().funtion();

            }

}

3匿名内部类

匿名内部类其实就是内部类的简写格式

定义匿名内部类的前提:

(1)内部类必须是继承一个类或者实现一个借口。

(2)匿名内部类的格式:new 父类或者借口(){定义子类的内容}

(3)匿名内部类就是一个匿名子类对象。

(4)匿名内部类中定义的方法最好不要超过3个。

 * */

public class 匿名内部类 

{

   

          public static void main(String[] args)

          {

                       new out1().function();

           }

}

abstract class absdemo

{

         abstract void show();

}

class out1

{

i         nt x=3;

/*

class inner extends absdemo

{

          void show()

          {

                       System.out.println("method.."+x);

          }

}

*/

          public void function()

          {

                      //new inner().show();

                     //new inner().show();

                     new absdemo()//

                     {

                                   void show()

                                    {

                                                   System.out.println("x="+x);

                                    }

                                   void abc()

                                    {

                                                    System.out.println("show.."+x);

                                    }

                     }.abc();

            }

}

4静态内部类

被static修饰一个类中的内部类。

静态内部类不用创建外部类对象就可以直接创建对象。

外部类名.内部类名 变量名 = new 外部类名.内部类名();

静态内部类可以定义静态成员。

因为静态内部类可以直接使用,无需创建外部类对象。

静态内部类中不能访问外部非静态成员。

因为创建静态内部类不需要外部类对象,也就是有可能没有创建外部类对象,使用外部类成员必须有外部类对象。

当内部类定义在外部类的成员位置时,而且非私有,可以在外部其他类中

可以直接建立内部咧对象。    

静态内部类只能访问外部类中的静态成员。出现的访问受限

在外部其他类中,如何直接访问static内部类的成员呢?

out.inner.funtion();

当内部类中定义了静态成员,那么该内部类也必须是静态的。

*/

public class static内部类

{

 

              public static void main(String[] args)

             {

                          new out.inner().function();

             }

}

class out

{

             private static int x=3;

             static class inner

             {

                        static void function()

                         {

                                      System.out.println("inner.."+x);

                         }

             }

             class inner2

             {

                         void show()

                         {

                                     System.out.println("inner2");

                         }

              }

              public static void method()

              {

                         inner.function();

              }

}

5、内部类访问规则

内部类可以直接访问外部类中的成员,包括私有

外部类要访问内部类,必须要建立内部类对象。

内部类之所有能访问外部类的成员,是因为内部类中持有了一个外部类中的引用outer.this

public class 内部类访问规则 

{

     public static void main(String[] args)

     {

           // outer out=new outer();

           //out.method();

      

      //直接访问内部类中的成员。

       outer. inner in=new outer().new inner();

       in.function();

        

    

     }

    

}

class outer

{

            int x=3;

            class inner//内部类,当内部类在外部类成员位置上时,可以被私有

            {

                         //int x=4;

                         void function()

                        {

                                      //int x=6;

                                      System.out.println("inner;"+x);//内部类之所有能访问外部类的成员,是因为内部类中

                                       //持有了一个外部类中的引用。outer.this

                         }

            }

           void method()

           {

                         //System.out.println(x);

                         inner in=new inner();

                         in.function();

            }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值