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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始







4、继承

4.7 接口

    接口应用综合案例

    代码:
  1. /*
  2. 笔记本电脑使用。
  3. 为了扩展笔记本的功能,但日后出现什么功能设备不知道。
  4. 因此需要定义一个规则,只要日后出现的设备都符合这个规则就可以了。
  5. 规则在java中就是接口。
  6. */
  7. interface USB{//暴露的原则
  8.        public void open();
  9.        public void close();
  10. }

  11. //实现原则
  12. //这些设备和电脑的耦合性降低了
  13. class UPan implements USB{
  14.        public void open(){
  15.             System.out.println("upan open");
  16.        }
  17.        public void close(){
  18.             System.out.println("upan close");
  19.        }
  20. }

  21. class UsbMouse implements USB{
  22.        public void open(){
  23.             System.out.println("usbMouse open");
  24.        }
  25.        public void close(){
  26.             System.out.println("usbMouse close");
  27.        }
  28. }

  29. class BookPC{
  30.        public static void main(String[] args){
  31.              //功能扩展了
  32.              useUSB(new UPan());
  33.        }
  34.        //使用原则
  35.        public static void useUSB(USB u){//接口类型的引用,用于接收(指向)接口的子类对象
  36.              if(u != null ){
  37.                   u.open();
  38.                   u.close();
  39.              }
  40.        }
  41. }
复制代码
   运行结果:



4.8 多态

    定义:某一类事物的多种存在形态。
   

    例:动物中猫,狗。
    猫这个对象对应的类型是猫类型:猫 x = new 猫();
    同时猫也是动物中的一种,也可以把猫称为动物:动物  y = new 猫();
    动物是猫和狗具体事物中抽取出来的父类型。
    父类型引用指向了子类对象。

    多态性简单说就是一个对象对应着不同类型。

    体现:
    父类或者接口的引用指向或者接收自己的子类对象。

    作用:
    多态的存在提高了程序的扩展性和后期可维护性。

   
    前提:
    1. 需要存在继承或者实现关系。
    2. 需要有覆盖操作。

   
    好处:
    提高了代码的扩展性,前期定义的代码可以使用后期的内容。
    弊端:
    前期定义的内容不能使用(调用)后期子类的特有内容。


    示例1:
  1. abstract class Animal{
  2.        abstract void eat();
  3. }

  4. class Dog extends Animal{
  5.        void eat(){
  6.             System.out.println("啃骨头");
  7.        }
  8.        void lookHome(){
  9.             System.out.println("看家");
  10.        }
  11. }

  12. class Cat extends Animal{
  13.        void eat(){
  14.             System.out.println("吃鱼");
  15.        }
  16.        void catchMouse(){
  17.             System.out.println("抓老鼠");
  18.        }
  19. }

  20. class Pig extends Animal{
  21.        void eat(){
  22.             System.out.println("饲料");
  23.        }
  24.        void gongdi(){
  25.             System.out.println("拱地");
  26.        }
  27. }

  28. class DuoTaiDemo{
  29.        public static void main(String[] args){
  30.             Cat c = new Cat();
  31.             Dog d = new Dog();

  32.              method(c);
  33.              method(d);
  34.              method(new Pig());
  35.        }

  36.        public static void method(Animal a){
  37.             a.eat();
  38.        }
  39. }
复制代码
   运行结果:


    示例2:
  1. class DuoTaiDemo{
  2.      public static void main(String[] args){
  3.           //自动类型提升,猫对象提升到了动物类型。但是特有功能无法访问,作用就是限制对特有功能的访问。
  4.           //专业讲:向上转型,将子类型隐藏。就不能使用子类的特有方法了。
  5.           Animal a = new Cat();
  6.           a.eat();
  7.           //a.catchMouse();//报错

  8.           //如果还想用具体动物猫的特有功能。
  9.           //你可以将该对象进行向下转型。
  10.           Cat c = (Cat)a; //向下转型的目的是为了能够使用子类中的特有方法。
  11.           c.eat();
  12.           c.catchMouse();

  13.           //注意:对于转型,自始至终都是子类对象在做类型的变化。
  14.           //Animal a = new Dog();
  15.           //Cat c = (Cat)a;//但是类型不能随意转换,否则可能会报出ClassCastException的异常
  16.      }

  17.      public static void method(Animal a){
  18.           a.eat();
  19.      }
  20. }
复制代码
    运行结果:


    示例3:
  1. /*
  2. 毕老师和毕姥爷的故事
  3. */
  4. class 毕姥爷{
  5.        void 讲课(){
  6.             System.out.println("管理");
  7.        }
  8.        void 钓鱼(){
  9.             System.out.println("钓鱼");
  10.        }
  11. }

  12. class 毕老师 extends 毕姥爷{
  13.        void 讲课(){
  14.             System.out.println("Java");
  15.        }
  16.        void 看电影(){
  17.             System.out.println("看电影");
  18.        }
  19. }

  20. class DuoTaiDemo{
  21.        public static void main(String[] args){
  22.             毕老师 x = new 毕老师();
  23.             x.讲课(); //Java
  24.             x.看电影(); //看电影

  25.             毕姥爷 y = new 毕老师();
  26.             y.讲课(); //Java
  27.             y.钓鱼(); //钓鱼

  28.             毕老师 z = (毕老师)y;
  29.             z.看电影(); //看电影
  30.       }
  31. }
复制代码
    运行结果:


    P.S.
    instanceof :用于判断对象的具体类型,只能用于引用数据类型判断,通常在向下转型前用于健壮性的判断。

    示例4:
  1. class DuoTaiDemo{
  2.        public static void main(String[] args){
  3.        }

  4.        public static void method(Animal a){
  5.             a.eat();
  6.             
  7.              if(a instanceof Cat){
  8.                   Cat c = (Cat )a;
  9.                   c.catchMouse();
  10.              }
  11.              else if (a instanceof Dog){
  12.                   Dog d = (Dog )a;
  13.                   d.lookHome();
  14.              }
  15.        }
  16. }
复制代码
   
    多态时,成员的特点:
    1. 成员变量
       编译时:参考引用型变量所属的类中是否有调用的成员变量。有,编译通过,没有,编译失败。
       运行时:参考引用型变量所属的类中是否有调用的成员变量,并运行该所属类中的成员变量。
       简单说:编译和运行都参考等号的左边。


    示例:
  1. class Fu{
  2.        int num = 3;
  3. }

  4. class Zi extends Fu{
  5.        int num = 4;
  6. }

  7. class DuoTaiDemo{
  8.        public static void main(String[] args){
  9.             Zi f1 = new Zi();
  10.             System.out.println(f1.num);
  11.             Fu f2 = new Zi();
  12.             System.out.println(f2.num);
  13.        }
  14. }
复制代码
   运行结果:


    2. 成员函数(非静态)
       编译时:参考引用型变量所属的类中是否有调用的函数。有,编译通过。没有,编译失败。
       运行时:参考的是对象所属的类中是否有调用的函数。
       简单说:编译看左边,运行看右边。


    示例:
  1. class Fu{
  2.        void show(){
  3.             System.out.println("fu show");
  4.        }
  5. }

  6. class Zi extends Fu{
  7.        void show(){
  8.             System.out.println("zi show");
  9.        }
  10. }

  11. class DuoTaiDemo{
  12.        public static void main(String[] args){
  13.             Fu f = new Zi();
  14.             f.show();
  15.        }
  16. }
复制代码
    运行结果:



    3. 静态函数
       编译时:参考的是对象所属的类中是否有调用的函数。
       运行时:参考的是对象所属的类中是否有调用的函数。
       简单说:编译和运行看左边。

    示例:
  1. class Fu{
  2.        static void method(){
  3.             System.out.println("fu static method");
  4.        }
  5. }

  6. class Zi extends Fu{
  7.        static void method(){
  8.             System.out.println("zi static method");
  9.        }
  10. }

  11. class DuoTaiDemo{
  12.        public static void main(String[] args){
  13.             Fu f = new Zi();
  14.             f.method();// fu static method
  15.             Fu.method();
  16.        }
  17. }
复制代码
   运行结果:


    4.9 内部类

    定义:
    将一个类定义在另一个类的里面,里面那个类就称为内部类(内置类,嵌套类)。

    访问特点:
    内部类可以直接访问外部类中的成员,包括私有成员。
    而外部类要访问内部类中的成员必须要建立内部类的对象。

    示例1:
  1. /*
  2. 内部类的设计:
  3. 分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容,这时候就定义内部类。
  4. */
  5. class Outer{
  6.        private int num = 3;

  7.        class Inner //内部类
  8.        {
  9.              void show(){
  10.                   System.out.println("show run..." + num);
  11.              }
  12.        }

  13.        public void method(){
  14.             Inner in = new Inner();
  15.             in.show();
  16.        }
  17. }

  18. class InnerClassDemo{
  19.        public static void main(String[] args){
  20.             Outer out = new Outer();
  21.             out.method();
  22.        }
  23. }
复制代码
   运行结果:


    示例2:  
  1. class Outer{
  2.        private int num = 3;

  3.        class Inner
  4.        {
  5.              void show(){
  6.                   System.out.println("show run..." + num);
  7.              }
  8.        }
  9. }

  10. class InnerClassDemo{
  11.        public static void main(String[] args){
  12.              //直接访问外部类中的内部类中的成员
  13.             Outer.Inner in = new Outer().new Inner();
  14.             in.show();
  15.        }
  16. }
复制代码
   运行结果:


    内部类的位置:
    内部类定义在成员位置上,可以被private、static成员修饰符修饰。被static修饰的内部类只能访问外部类中的静态成员。

    示例1:

  1. class Outer{
  2.        private static int num = 3;

  3.        static class Inner
  4.        {
  5.              void show(){
  6.                   System.out.println("show run..." + num);
  7.              }
  8.        }
  9. }

  10. class InnerClassDemo{
  11.        public static void main(String[] args){
  12.              //如果内部类是静态的,相当于一个外部类
  13.             Outer.Inner in = new Outer.Inner();
  14.             in.show();
  15.        }
  16. }
复制代码
    运行结果:



    示例2:如果内部类是静态的,内部类成员也是静态的,可以不用创建内部类对象,直接调用。
  1. class Outer{
  2.        private static int num = 3;

  3.        static class Inner
  4.        {
  5.              static void show(){
  6.                   System.out.println("show run..." + num);
  7.              }
  8.        }
  9. }

  10. class InnerClassDemo{
  11.        public static void main(String[] args){
  12.             Outer.Inner.show();
  13.        }
  14. }
复制代码
   运行结果:


    P.S.        
    1、如果内部类中定义了静态成员,该内部类也必须是静态的!

    示例:
  1. class Outer{
  2.      private static int num = 3;

  3.      static class Inner
  4.      {
  5.           static void show(){
  6.                System.out.println("show run..." + num);
  7.           }
  8.      }
  9. }
复制代码

    2、为什么内部类能直接访问外部类中的成员呢?
         那是因为内部类持有了外部类的引用,外部类名.this。  

    示例:
  1. class Outer{
  2.        int num = 3;
  3.        class Inner{
  4.              int num = 4;
  5.              void show(){
  6.                    int num = 5;
  7.                    System.out.println(num);
  8.                    System.out.println(this.num);
  9.                    System.out.println(Outer.this.num);
  10.              }
  11.        }
  12.        void method(){
  13.              new Inner().show();
  14.        }
  15. }

  16. class InnerClassDemo{
  17.        public static void main(String[] args){
  18.              new Outer().method();
  19.        }
  20. }
复制代码
    运行结果:


    3、内部类定义在局部位置上,也可以直接访问外部类中的成员。
         同时可以访问所在局部中的局部变量,但必须是被final修饰的。

    示例:
  1. class Outer{
  2.        int num = 3;
  3.        void method(final int y){
  4.              final int x = 9;
  5.              class Inner{
  6.                    void show(){
  7.                         System.out.println("show..." + x + "," + y);
  8.                    }
  9.              }
  10.             Inner in = new Inner();
  11.             in.show();
  12.        }
  13. }

  14. class InnerClassDemo{
  15.        public static void main(String[] args){
  16.              new Outer().method(4);
  17.        }
  18. }
复制代码
    运行结果:


     匿名内部类

    定义:
    就是内部类的简化写法。

    前提:
    内部类可以继承或实现一个外部类或者接口。

    格式:
    new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}


    简单理解:
    就是建立一个带内容的外部类或者接口的子类匿名对象。


    什么时候使用匿名内部类呢?
    通常使用方法是接口类型参数,并且该接口中的方法不超过三个,可以将匿名内部类作为参数传递。

    好处:
    增强阅读性。

    示例1:
  1. abstract class Demo{
  2.        abstract void show();
  3. }

  4. class Outer{
  5.        int num = 4;

  6.        void method(){
  7.              new Demo(){//匿名内部类
  8.                    void show(){
  9.                         System.out.println("show......" + num);
  10.                   }
  11.              }.show();
  12.        }
  13. }

  14. class InnerClassDemo{
  15.        public static void main(String[] args){
  16.              new Outer().method();
  17.        }
  18. }
复制代码
    运行结果:


    示例2:  
  1. interface Inter{
  2.        void show1();
  3.        void show2();
  4. }

  5. class Outer{
  6.        public void method(){
  7.             Inter in = new Inter(){
  8.                    public void show1(){
  9.                           System.out.println("...show1...." );
  10.                    }
  11.                    public void show2(){
  12.                           System.out.println("...show2...." );
  13.                    }
  14.             };
  15.             in.show1();
  16.             in.show2();
  17.        }
  18. }

  19. class InnerClassDemo{
  20.        public static void main(String[] args){
  21.              new Outer().method();
  22.        }
  23. }
复制代码
    运行结果:


    示例3:  
  1. interface Inter{
  2.        void show1();
  3.        void show2();
  4. }

  5. /*
  6. 通常的使用场景之一:
  7. 当函数参数是接口类型时,而且接口中的方法不超过三个。
  8. 可以用匿名内部类作为实际参数进行传递。
  9. */
  10. class InnerClassDemo{
  11.       public static void main(String[] args){
  12.              show(new Inter(){
  13.                    public void show1(){
  14.                         System.out.println("...show1..." );
  15.                    }
  16.                    public void show2(){
  17.                         System.out.println("...show2..." );
  18.                    }
  19.             });
  20.        }
  21.        public static void show(Inter in){
  22.             in.show1();
  23.             in.show2();
  24.        }
  25. }
复制代码
    运行结果:


    对象的初始化过程

    示例:
  1. class Fu{
  2.        int num = 9;

  3.        {
  4.             System.out.println("Fu" );
  5.        }

  6.       Fu(){
  7.              super();//Object
  8.              //显示初始化
  9.              //构造代码块初始化
  10.             show();
  11.        }
  12.        void show(){
  13.             System.out.println("fu show " + num);//被覆盖,运行子类的
  14.        }
  15. }

  16. class Zi extends Fu{
  17.        int num = 8;

  18.       {
  19.             System.out.println("Zi" );
  20.       }

  21.       Zi(){
  22.              super();
  23.              //显示初始化
  24.              //构造代码块初始化
  25.             show();
  26.       }

  27.        void show(){
  28.             System.out.println("zi show " + num);
  29.        }
  30. }

  31. public class Demo{
  32.        public static void main(String[] args){
  33.              new Zi();
  34.        }
  35. }
复制代码
  运行结果:



~END~



~爱上海,爱黑马~





36 个回复

倒序浏览
真的够详细的。。。
回复 使用道具 举报
顶!顶!顶!顶!
回复 使用道具 举报
好好好,有更新了。
回复 使用道具 举报
顶一个,详细
回复 使用道具 举报
学习中  加油
回复 使用道具 举报
真是辛苦你了,这么贴心:{:2_32:}
回复 使用道具 举报
赞一个。
回复 使用道具 举报

真的够详细的。。。
回复 使用道具 举报
今天要复习呀,今天要复习~~
回复 使用道具 举报
汪磊の 来自手机 中级黑马 2015-6-20 09:34:24
11#
赞一个!!
回复 使用道具 举报
感觉向上转型还要多练练。模模糊糊的。
回复 使用道具 举报
赞一个!
回复 使用道具 举报
搞基的厉害咯。
回复 使用道具 举报
赞一个,阳哥加油
回复 使用道具 举报
非常好啊
回复 使用道具 举报
阳哥的总结就是这么牛
回复 使用道具 举报
好详细哦。
回复 使用道具 举报
刚学完,很详细,复习用 !!!!!!!!!!!!!!!!!!!!!!!赞
回复 使用道具 举报
够详细的赞一个
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马