上海传智播客JAVASE_day10学习笔记

《第十天总结》 张伦琦
《多态,Object 类,内部类》
1.    多态    
    1.1多态引入    
    一、多态的体现:父类的引用或者接口的引用指向了自己的子类对象。
        Dog d = new Dog();//Dog对象的类型是Dog类型。
        Animal a = new Dog();//对象的上转型。Dog对象的类型右边是Dog类型,左边Animal类型。
    二、判定多态的依据(记忆)
        1.存在继承体系(泛化体系)
        2.存在override(方法的实现和方法的覆盖)
        3.存在父类型的引用操纵子类型的对象。
    三、多态的好处和弊端
        好处:提供了程序的扩展性。和灵活性。为我们开闭原则提供服务。
        弊端:通过父类型的引用只能操作父类中的方法,不能操纵子类特有的方法。
    四、对象的上转型(编译是时,javac时)
        1.将子类型提升为父类型(向上转型)
        2.提高了程序的扩展性
        3.隐藏了子类型,不能使用子类型特有的方法,特有数据。
    五、对象的下转型(运行时,java时)
        1.将转换为父类型的子类型对象重新转换为子类型(向下转型)
        2.上转型是下转型的前提。
        3.下转型可以使用子类型中特有的内容。
        4.易引发ClassCastException异常。为避免此问题,向下转型前,做类型的判断。
           判断类型用的是关键字 instanceof
    六、类型转型总结
        1,什么时候使用向上转型呢?
            提高程序的扩展性,不关心子类型(子类型被隐藏)。
            需要用子类的特有方法吗?不需要,向上转型。
        2,什么时候使用向下转型呢?
            需要使用子类型的特有方法时。下转型
            但是一定要使用 instanceof 进行类型的判断。避免发生 ClassCastException
    七,多态中的变量和方法
       1.成员方法:和子类型对象相关的方法。能多态
           编译的时候看左边,运行的时候看右边。
       2.成员变量(直接使用)
           编译的时候看左边,运行的时候看左边。
       3.静态方法:
           编译的时候看左边,运行的时候看左边。
       4. 静态变量(直接使用)
           编译的时候看左边,运行的时候看左边。

    1.2多态中的数据和方法

    对象的上转型:
       1. 编译时。
       2.子类特有方法和变量被屏蔽。必须看左边的父类型。

    对象的下转型:
       1.运行时。
       2.要找到子类型被屏蔽的特有的方法和数据,要下转型。
       3.为了防止 ClassCastException:类型转换异常要先用instanceof判定
         对象上转型是下转型的前提。
       4.例子:
       class Animal{
          public void eat(){
            System.out.println("动物吃");
         }
       }
       class Dog extends Animal{
         public void eat(){//重写
           System.out.println("狗吃骨头");
         }
         public void watchHome(){
           System.out.println("狗看家");
         }
       }
       class Cat extends Animal{
       }

       class Demo {
        public static void main(String[] args) {
        //编译时候,对象的上转型。Dog对象转成Animal类型,子类特有功能和数据被屏蔽
        Animal a=new Animal();//OK
        //a.eat();//ok
        //a.watchHome();
        // 运行时,对象下转型,必须要找到子类特有的功能和数据
        //如果类型不对 ClassCastException:类型转换异常为了避免这种异常。
        System.out.println(a instanceof Dog);
        if (a instanceof Dog){
            Dog d=(Dog)(a)
        }
        //Dog d=(Dog)(a);
        //d.watchHome();
    }
    }
例子2:
class Father{
    int age=50; static int score=25;
    public void show(){
      System.out.println("老爸的show()");
    }
    public static void show1(){
      System.out.println("老爸静态的show()");
    }
}
class Son extends Father{
    //int age=20;
    static int score=75;
    public void show(){
      System.out.println("儿子的show()");
    }
    public static void show1(){
      System.out.println("儿子静态的show()");
    }
    public void show2(){
        //方法在寻找变量的时候是先己后父亲
      System.out.println(age);
    }
}
class DuotaiDemo2 {
    public static void main(String[] args) {
        Father f2=new Son();
        System.out.println(f2.age);// 50  父类的
        //System.out.println(f2.score);// 25 父类的
        f2.show();//儿子的 这里是多态
        //f2.show1();//父类的
        Son s=new Son();
        s.show2();
    }
}

    1.3多态的练习一—笔记本电脑
    见其他文档


    1.4多态的练习二—教练运动员
/*
 篮球教练:吃饭,教球,说英语
 篮球球员:吃饭,玩球,说英语
 足球教练:吃饭,教球
 足球球员:吃饭,玩球
*/
interface EnglishSpeakable{
    public void speakEnglish();
}
abstract class Person{
    public abstract void eat();
}
abstract class Player extends Person{
    public abstract void play();
}
abstract class Teacher  extends Person{
    public abstract void teach();
}
class BasketBallPlayer  extends Player implements EnglishSpeakable {
    public void speakEnglish(){
        System.out.println("篮球运动员说英语");
    }
    public  void eat(){
        System.out.println("篮球运动员吃水煮牛排");
    }
    public  void play(){
        System.out.println("篮球运动员玩转NBA");
    }
}
class FootBallPlayer  extends Player   {
    public  void eat(){
        System.out.println("足球运动员吃水煮开水");
    }
    public  void play(){
        System.out.println("足球运动员玩少林足球");
    }
}
class BasketBallTeacher  extends Teacher  implements EnglishSpeakable {
    public  void eat(){
        System.out.println("篮球教练油炸牛排");
    }
    public  void teach(){
        System.out.println("篮球教练教篮球");
    }
    public void speakEnglish(){
        System.out.println("篮球教练说英语卖球员");
    }
}
class FootBallTeacher  extends Teacher  {
    public  void eat(){
        System.out.println("足球教练水煮凉水");
    }
    public  void teach(){
        System.out.println("足球教练教球员看少林足球");
    }
}
class DuoTaiTest2 {
    //这个方法中既有对象上转型又有对象下转型
    public static void run(Object[] objs) {
        for (int i=0;i<objs.length ;i++ ){
               Object obj=objs[i];
               if (obj instanceof Person){
                   Person p=(Person)(obj);
                   p.eat();
               }
               if (obj instanceof Player){
                   Player p=(Player)(obj);
                   p.play();
               }
               if (obj instanceof Teacher){
                   Teacher t=(Teacher)(obj);
                   t.teach();
               }
               if (obj instanceof EnglishSpeakable){
                   EnglishSpeakable e=(EnglishSpeakable)(obj);
                   e.speakEnglish();
               }
        }
    }
    public static void main(String[] args) {
     /*没有多态
      BasketBallTeacher  bbt=new BasketBallTeacher();
      bbt.eat();
      bbt.teach();
      bbt.speakEnglish();
      */
      /*
      以人为基准进行多态
      Person  bbt=new BasketBallTeacher();
      bbt.eat();
      */
      /*以接口为基准多态
       EnglishSpeakable  bbt=new BasketBallTeacher();
       bbt.speakEnglish();
       */
      BasketBallTeacher bbt= new BasketBallTeacher();
      BasketBallPlayer bbp=new BasketBallPlayer();
      FootBallTeacher fbt=new FootBallTeacher();
      FootBallPlayer fbp=new FootBallPlayer();
      Object[] objs={bbt,bbp,fbt,fbp};//对象上转型
      run(objs);
    }
}

2.    Object类    
    2.1object的类和Api
        Object是所有类的父类

            方法

         protected  Object clone() (不学)
              创建并返回此对象的一个副本。
         boolean equals(Object obj) (要学)
              指示其他某个对象是否与此对象“相等”。
         protected  void finalize()
              当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
         Class<?> getClass()
              返回此 Object 的运行时类。
         int hashCode() (要学)
              返回该对象的哈希码值。
         void notify()
              唤醒在此对象监视器上等待的单个线程。
         void notifyAll()
              唤醒在此对象监视器上等待的所有线程。
         String toString() (要学)
              返回该对象的字符串表示。
         void wait()
              在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
         void wait(long timeout)
              在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
         void wait(long timeout, int nanos)
              在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。


            

            
    2.2object的toString()方法和hashCode()方法
            String toString() (要学) 返回该对象的字符串表示。

             public String toString() {
                       //类名 "@"十六进制的哈希值
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
             }


             int hashCode() (要学)
                      返回该对象的哈希码值。
             public native int hashCode();//native表示该方法不是Java写的,没有方法体


    2.3object的equal方法    
        boolean equals(Object obj) (要学)
            指示其他某个对象是否与此对象“相等”。

3.    内部类    
    3.1成员内部类    
        用类描述事物
            事物当中有事物。类中类,内部类
            
            class Car{
               class Enginee{
            
              }
            }
            内部类定义:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
            访问特点(是否使用内部类的条件)
                1.内部类可以直接访问外部类中的所有成员,包括私有成员。
                2.外部类要访问内部类中的成员必须要建立内部类的对象。

            内部类对象有两种创建方式
                1.在外部类中创建内部类对象
                2.在外部类外直接创建内部类对象,如果内部类是私有的,这种方式不行

            一个外部类可以有多个内部类,内部类中还可以有层内部类。
        成员内部类一般不要直接对外暴露。
        class Body{
          //暴露的成员内部类
          private class Heart{
              public void speed(){
                //心脏加速
              }
              public void cut(){
                //心脏切除
              }
          }
          public void run(){
              Heart h=new Heart();
             if(你是医生){//此处可以加判断使操作更加安全。
                h.speed();
                h.cut();
             }
          }
        }
        class Demo{
            public static void main(String[] args) {
                //Body.Heart bh=new Body().new Heart();
                //bh.speed();//不安全,将内部类私有化
                //bh.cut();
            }
        }
        */
        class Outter{
            //外部类私有成员,内部类能直接访问
            private  int i=10;
            //class Inner编译以后生成Outter$Inner.class文件,成员内部类
            class Inner{
                static final int age=80;//成员内部类中处理静态的常量外,不能存在其他静态的东西
                //Inner成员方法,必须创建Inner对象
                public void show(){
                    System.out.println(i);//内部类中可以直接访问外部类的所有成员包括私有包括静态
                }
            }
            public void method(){
                //1.在外部类中创建内部类对象
                Inner inner=new Inner();
                inner.show();
            
            }
        }
        class ChengYuanNeiBuLeiDmeo {
            public static void main(String[] args) {
                /*
                Outter outter=new Outter();
                outter.method();
                */
                //2.在外部类外直接创建内部类对象
                /*
                Outter o=new Outter();//创建外部类对象
                Outter.Inner oi=o.new Inner();
                oi.show();
                */
                //外部类名.内部类名 变量名=外部类对象.内部类对象
                Outter.Inner oi=new Outter().new Inner();
                oi.show();
            }
        }

    3.2静态内部类    
            /*
        静态内部类:就是带有static成员内部类
        1.静态内部类中可以有静态的成员
          成员内部类不能有静态的东西,如果有也只能是static final 常量
        2.静态内部类中不能直接访问外部类的成员变量,
          成员内部类中能直接访问外部类的成员变量
         原因是:成员内部类持有着所在外部类对象的引用所有可以直接访问外部类的成员变量。
             静态内部类不持有所在外部类对象的引用所有不能直接访问外部类的成员变量。
        */

    3.3局部内部类    
                /*
        局部内部类:定义在方法中的类。
        1.static ,private,public,都不能修饰局部内部类
        2.final内部类是可以的,abstract内部类也可以
        3.局部内部类不能在外部类外创建对象。只能在所在方法中创建对象
        4.局部内部类可以直接访问外部类的成员变量。和静态变量(持有外部类对象的引用)
        */

    3.4匿名内部类    
                /*
        如果匿名内部类不能给你带来方便,那就用有名内部类。
        */
        abstract class Father{
            public abstract  void show();
        }
        class Outter{
            public void method(){
                //()此次加{这里写代码};
                //局部匿名内部类
                /*
                Father f=new Father(){
                        public   void show(){
                           System.out.println("你又长见识了吧吧!");
                        }
                
                };
                f.show();
                */
                //匿名内部类创建匿名对象,直接使用方法
                new Father(){
                        public   void show(){
                           System.out.println("你又长见识了啊啊啊啊啊!");
                        }
                
                }.show();
            }
            //内部类可以继承其他类,而外部类不必继承。(1.局部内部类编译)
            class Son extends Father{
                public  void show(){
                  System.out.println("哈哈");
                }
            }
            //外部类的成员变量,Son是一个Father的子类,如果说Son只用一次,那么这个类名可以省略不写。
           //Father f =new Son();

           //以下是一个成员匿名内部类,必须是一个类的子类或者一个接口的实现类
           //只能直接创建对象。
           Father f =new Father(){
                public  void show(){
                  System.out.println("呵呵长见识了吧");
                }
           };
        }
        class NiMingNeiBuLeiDmeo {
            public static void main(String[] args) {
                Outter o=new Outter();
                //o.f.show();
                o.method();
            }
        }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值