黑马程序员技术交流社区

标题: 【阳哥笔记】极速秒杀Java基础之笔记系列—Day10(继承)! [打印本页]

作者: 阳哥忠粉    时间: 2015-6-4 22:59
标题: 【阳哥笔记】极速秒杀Java基础之笔记系列—Day10(继承)!





笔记总链接:http://bbs.itheima.com/thread-200600-1-1.html

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~



~爱上海,爱黑马~






作者: zlynnb2015    时间: 2015-6-5 00:10
真的够详细的。。。
作者: 熊乾坤    时间: 2015-6-5 19:14
顶!顶!顶!顶!
作者: 朱吕龙    时间: 2015-6-6 21:39
好好好,有更新了。
作者: 307323665    时间: 2015-6-6 22:27
顶一个,详细
作者: wx_iAuO26mH    时间: 2015-6-7 09:51
学习中  加油
作者: wx_d9b6mRbI    时间: 2015-6-7 10:37
真是辛苦你了,这么贴心:{:2_32:}
作者: 新缘    时间: 2015-6-9 22:26
赞一个。
作者: 魏海洲    时间: 2015-6-10 22:41

真的够详细的。。。
作者: Jackie7    时间: 2015-6-20 09:31
今天要复习呀,今天要复习~~
作者: 汪磊の    时间: 2015-6-20 09:34
赞一个!!
作者: Jackie7    时间: 2015-6-21 09:32
感觉向上转型还要多练练。模模糊糊的。
作者: 繁星中的白矮星    时间: 2015-6-24 15:29
赞一个!
作者: heisedelangzi    时间: 2015-7-2 00:38
搞基的厉害咯。
作者: 繁华落尽    时间: 2015-7-3 21:45
赞一个,阳哥加油
作者: 宝马X6    时间: 2015-7-3 22:07
非常好啊
作者: 张业涛    时间: 2015-7-3 22:11
阳哥的总结就是这么牛
作者: 张先生丶丶    时间: 2015-7-4 12:20
好详细哦。
作者: 星痕-凌    时间: 2015-7-16 21:57
刚学完,很详细,复习用 !!!!!!!!!!!!!!!!!!!!!!!赞
作者: 鹰隼展翼    时间: 2015-7-16 22:37
够详细的赞一个
作者: 小p    时间: 2015-7-16 23:01
吾日三省吾身
作者: 王勋亮    时间: 2015-7-26 13:20
太详细了!!!大爱!!!
作者: 王勋亮    时间: 2015-7-26 17:23
Object类不在这个么?
作者: 潜力良驹    时间: 2015-7-26 20:57
顶顶顶顶
作者: 陈建民1    时间: 2015-7-26 21:15
经典必看,赞一个。。
作者: 王勋亮    时间: 2015-7-27 09:37
看的真是方便啊!!!
作者: lizf2010    时间: 2015-7-27 11:23
都是用的毕姥爷的例子啊
作者: 一城一世界    时间: 2015-7-27 11:28
牛逼,继续分享~
作者: 王竹根    时间: 2015-7-27 12:22
好。很好的资料。。大赞
作者: DreamStart    时间: 2015-7-28 10:36
好精彩,收获很大
作者: 放心飞    时间: 2015-8-27 10:00
越来越难,加油理解。再前行。
作者: hiahia    时间: 2015-9-12 16:39
牛叉的阳哥。
作者: 插兜    时间: 2015-9-12 17:54
阳哥,我是你粉丝
作者: yangshibai    时间: 2015-9-21 23:27
来温习一下。。
作者: lixy    时间: 2016-1-5 10:35
初始化的过程要是再讲一讲就更好了。这一块一直都没有吃透的感觉
作者: lixy    时间: 2016-1-5 17:56
看了很久,还是不太懂
作者: 雪中飞    时间: 2016-1-6 21:32
好详细,总结的棒棒哒




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2