上海传智播客JAVASE_day09学习笔记

来源:互联网 发布:炭知天下龙泽路手机号 编辑:程序博客网 时间:2024/05/01 19:15
《第九天总结》 张伦琦
《继承、抽象类,接口、多态》
1.    继承    
    1.1继承中的对象构造顺序    
    A.自己一句话总结:先父后子,首先是父类的静态的东西经过(静态变量初始化,静态代码块的顺序),
            然后再是子类的静态的东西的开始,再者就是父类的成员的东西(成员变量,构造代码块,构造方法)
            再是子类的成员的东西。


    B.对象的创建过程
    1.加载类:处理静态的东西,先父后子
        父类静态变量默认初始化
        父类静态变量显示初始化
        父类静态代码块
        子类静态变量默认初始化
        子类静态变量显示初始化
        子类静态代码块
    2.建对象:处理成员的东西,先父后子
        父类成员变量默认初始化
        父类成员变量显示初始化
        父类构造代码块
        父类构造函数
        子类成员变量默认初始化
        子类成员变量显示初始化
        子类构造代码块
        子类构造函数

    C.super()是什么?
        代指父类的某个构造方法。(构造方法不能继承,还得用,给起了个名字。)
        必须得找到父类构造方法。
    
    
    D.第一种形式的总结:(理解)
        1.除Object类外,所有类都有父类。
        2.对象的构造顺序是自上而下的。也就是初始化父类的部分,再初始化子类的部分。
        3.所有类的所有构造方法第一句必须是super([x,y,z])
        默认方案:构造方法第一句默认隐式调用super();
        指定方案:1.构造方法第一句显式调用super([x,y,z])
                  2.构造方法第一句显式调用this([x,y,z])...>super([x,y,z])
    

    1.2继承中的override    
    A.自己一句话总结:override,就是重写,就是子类把父类中的同名方法再写一遍!

    B.方法重写:override
        在子类中重写编写从父类继承下来的方法。

    C.方法重载注意:
        1.子类方法和父类方法的头部相同。
        2.子类覆写父类的方法权限不能小于父类。

    D.super和this
        super代表子类对象中父类那一部分,可以用来显示调用父类的部分.

    E.重载和重写(记忆)
        A.Java中的override(重写:动态多态的基础)?
            1.子父类中,存在同名方法名
            2.同名方法之间的参数列表相同
            3.子类方法的返回值  ==  父类方法的返回值
            4.子类方法的访问权限>=父类方法的访问权限
            5.private、static(有人说静态覆盖静态)、final方法均不可重写。
        B.Java中的overload(重载:静态多态的基础)?
            1.同一类中,存在同名方法
            2.同名方法之间的参数列表不同
            3.同名方法之间的返回值,没有关系
            4.同名方法直接的访问权限,没有关系
            5.private、static、final方法均可以重载。

        举例
            getMax(int i,int j)
            getMax(int i,int j,int k)
            getMax(int i,int j,int k,int l)


    1.3继承中的this和super总结    
    A.自己一句话总结:this是地址,super是一块内存区域.
        1.this代表当前对象,super代表当前对象中存放从父类继承下来的那片内存空间。
        2.this可以直接使用,因为它就是对象
        3.super不能直接使用,因为它只是一个对象的一个部分。
        4.this和super在访问它们各自的成员的时候用法非常相似            
        5.this()代表本来的某个构造方法,super()代表父类的某个构造方法。
        6.除Object类外,所有类的构造方法第一句默认都是super()
          无论如何你要保证能找到父类的构造方法。


    1.4继承中的final
    A.自己一句话总结:final可以修饰类,方法,和数值.被final修饰的类是断子绝孙类,不能被继承了,
            只能自己创造对象;被final修饰的方法不能被重写可以被继承,被final修饰的数值
            会变成常量。

    B.继承好处:
            父类的方法和变量能直接被子类继承。并且可以被子类修改
    C.继承坏处:
                如果父类的方法比较重要,继承可以,但修改不太合适。
            你可以将该方法声明为final
            final是终态方法,可以被继承,但是不可以被修改。

    D.如果类中的所有方法都是final的,干脆类变成final
       final class不可以被继承,不能有子类,亦不能有孙类,断子绝孙类
       final类中的所有方法都是final的。

    E.final变量,变量的值不能被改变。成了常量。
       常量的命名规则是 XXX_YYY_ZZZ
       有名称的常量的好处是,能一改全改,见名知意。
      
        1.类天生就能被继承,天生可以做父类
        2.final类不可以被继承。

    F.final总结(记忆)
        final变量:变量中的内容不能被改变。(不能被赋值的变量),不能被修改的数据
            1.变量的值不能修改。声明常量。
            2.常量有名称要大写字母加_
            3.static fianl data: 属于类的只有一份的不能改变的常量。
            4.值一开始就指定好。在对象构造以前指定好值。
        final方法:方法中的内容不能被改变。(不能被重写的方法),不能被修改的方法
            1.方法可以继承
            2.不能被重写的方法。
        final类:类不能被继承。不能被修改的类




2.    抽象类    
    2.1抽象类的引入    

    自己的一句话总结:

                 抽象abstract可以修饰类,方法,修饰类是代表这个抽象类是天生爸爸类,不能直接创造对象

               天生就是给其他类继承的;抽象方法时,代表这个类没有方法体,就是给其他类重写的,但是有
               抽象方法的类必须要是抽象类



    A.抽象类引子:
        动物  跑 吼叫
        Dog   跑 吼叫
        Wolf  跑 吼叫
            class Dog{
                public void run(){
                    System.out.println("狗跑");
                }
                public void bark(){
                    System.out.println("狗叫");
                }
            }
            class Wolf{

                public void run(){
                    System.out.println("狼跑");
                }
                public void bark(){
                    System.out.println("狼叫");
                }
            }

    B.现在有重复代码 咋办?
        弄一个父类Animal,狼和狗还不一样?咋办?
        只知道有一个(跑)功能,但不知道这个(跑)功能的具体实现。
        abstract方法是 只有方法头没有方法体,叫抽象方法。代码实现不具体。
        方法是抽象的,说明方法没有代码,方法不能执行。如果Animal能创建对象
        用Animal对象奔跑,岂不是要出事。最好是不跑。对象不能创建。
        abstract类,该类不能创建对象。

    C.为啥写抽象类?
         1.因为编写类的功能信息量不够,Animal不知道具体怎么run()也不知道具体怎么bark()
         2.抽象类天生就是当爹的。子孙满堂类。


    D.抽象类的注意
        1.abstract方法是 只有方法头没有方法体,叫抽象方法。
        2.abstract类,该类不能创建对象.
        3.抽象方法一定在抽象类中。
        4.抽象类中不一定有抽象方法。
        5.如果继承下来了抽象方法
           a.子类也是抽象类(Dog,Wolf变成抽象类)
           b.重写所有的抽象方法。

    E.abstract总结:(记住)
        1.抽象方法:不能直接运行的方法。(没有方法体)
        2.抽象类:  不能实例化对象的类。
        3.抽象方法必须在抽象类中。

    F.关于抽象类FAQ(理解,面试题)
        1.抽象方法必须在抽象类中吗?
        是的,抽象方法必须在抽象类中,因为抽象方法只有方法头没有方法体不能执行,不能被对象调用。
        那么这个类直接创造对象的条件就不具备,要想防止被对象调用只有让方法所在的类不能产生对象,
        只好将方法所在的类声明为抽象类。
        
        2.抽象类中必须有抽象方法吗?
        未必,抽象类只是让类不能产生对象。只是说明一个类不具备直接创造对象的条件,这个条件并不一
        定和抽象方法相关。适配器可以反驳之。
        
        3.抽象类一定是父类吗?
        是的。抽象类不能产生对象,因此它自己不能工作。如果它没有子类,那就是又不让产生子类进行工
        作,请问你设计这么一个类还有什么意义呢?
        
        4.子类继承抽象类必须要实现其中的抽象方法吗?
        是的,如果子类继承了一个抽象类,那么子类要么全部实现它的所有抽象方法,要么子类也必须是抽
        象类。因为抽象方法必须在抽象类中。
        
        5.抽象类不能产生对象,那抽象类中有构造方法吗?
        有构造方法,因为抽象类必须是父类。它的子类在创造对象的时候一定会用到父类的构造方法,如果没
        有构造方法,子类怎么调用。抽象类本身不能实例化对象,因此它抽象类的构造方法不是用来自己实例
        化对象的,而是为其子类实例化对象提供服务的。
        
        6.存在抽象的数据吗?abstact int a=5;
        不存在。数据都是具体的,没有抽象的,抽象的数据压根就没有意义。
        
        7.存在私有的抽象的方法吗?
        不存在。私有方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾。
        private abstract 不能共存
        
        8.存在静态的抽象方法吗?
        不存在。静态方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾
        static abstract 不能存
        
        9.存在最终的抽象方法吗,存在最终的抽象的类吗?
        不存在。最终方法是不参与重写的,而抽象方法要求必须进行实现性质的重写。两者矛盾。
        最终类是不参与继承的,而抽象类是必须进行继承。
        ( 最终的类是断子绝孙的类,抽象的类是子孙满堂的类)两者矛盾。
        final  abstract 不能共存


    2.2抽象类的练习    
                /*
            需求:
                程序员有姓名,工号,薪水,项目奖金,工作内容。
                业务员有姓名,工号,薪水,业务奖金,工作内容。
                对给出需求进行数据建模。
            分析:
                    程序员:
                       属性:姓名,工号,薪水,项目奖金
                       方法:工作内容(程序开发)。
                    业务员:
                       属性:姓名,工号,薪水,业务奖金
                       方法:工作内容(程序销售)。

                    共同的东西:
                        属性:姓名,工号,薪水
                        方法:工作内容
            代码:
                class    Programmer{
                    //属性  姓名,工号,薪水,项目奖金
                    String name;
                    String id;
                    double salary;
                    double projectBonus;

                    //方法  工作内容(程序开发)。
                    public void work(){
                        System.out.println("程序开发");
                    }

                }
                class    Saler{
                    //属性  姓名,工号,薪水,业务奖金
                    String name;
                    String id;
                    double salary;
                    double saleBonus;

                    //方法  工作内容(程序销售)。
                    public void work(){
                        System.out.println("程序销售");
                    }
                }
                现在可以运行,但是有代码重复。
        */
        abstract class Clerk{
            //属性:姓名,工号,薪水
            private String name;
            private String id;
            double salary;
            public Clerk(){
                //抽象类中可以有抽象方法,为子类构建对象做准备。
            }
            public Clerk(String name,String id,double salary){
                this.name=name;
                this.id=id;
                this.salary=salary;
            }
            //方法:工作内容,获取收入
            public abstract void work();
            public abstract double getMoney();
            public void show(){
                System.out.println("name="+name+",id="+id+"salary"+salary);
            }
        }
        class    Programmer extends Clerk{
            //属性:项目奖金
            private double projectBonus;
            public Programmer(){
               super();//默认
            }
            public Programmer(String name,String id,double salary,double projectBonus){
                super(name, id, salary);//调用父类构造方法,来初始化变量
                this.projectBonus=projectBonus;
            }
            //方法:重写,工作内容(程序开发)。
            public void work(){
                System.out.println("程序开发");
            }
            public double getMoney(){
                //this.salary找不到,私有要去掉
                //this.salary找不到,私有要去掉
                return  super.salary+this.projectBonus;
            }
        }
        class    Saler  extends Clerk{
            //属性:业务奖金
            private double saleBonus;
            public Saler(){
                super();//默认
            }
            public Saler(String name,String id,double salary,double saleBonus){
                super(name, id, salary);//调用父类构造方法,来初始化变量
                this.saleBonus=saleBonus;
            }
            //方法:重写,工作内容(程序销售)。
            public void work(){
                System.out.println("程序销售");
            }
            public double getMoney(){
                return  this.salary+this.saleBonus;
            }
        }
        //测试类
        class AbstractTest {
            public static void main(String[] args) {
                Programmer p=new Programmer("张三","bd001",8000.23,12000.25);
                p.work();
                double money=p.getMoney();
                System.out.println(money);
                Saler s=new Saler("李四","bd002",4000.23,52000.25);
                s.work();
                money=s.getMoney();
                System.out.println(money);
                s.show();
                p.show();
            }
        }


3.    接口    
    3.1接口引入    
    A.自己的一句话总结:interface修饰,里面的方法全部是public abstract的,里面的数值全部是public static final的,
                使用接口必须使用里面的所有东西。

    
    B.接口引入的例子
        面向接口编程
        访问接口:getter和setter
        如果出来这个全部抽象方法的类?
        abstract class Animal{
            public abstract void eat();
            public abstract void sleep();
            public abstract void run();

        }

        class Dog extends Animal{
        public  void eat(){
            System.out.println("狗吃骨头");
            }
        public  void sleep(){
            System.out.println("狗天天睡");
            }
        public  void run(){
            System.out.println("人模狗样");
        }
        }

        class Cat extends Animal{
        public  void eat(){
            System.out.println("猫吃鱼");
        }
        public  void sleep(){
            System.out.println("猫白天睡");
        }
        public  void run(){
            System.out.println("人模猫样");
        }
        }

        动物中所有的方法都是抽象的。
         interface接口:
         1.接口中的方法全是抽象的。
         2.接口中的方法全是public的

    C.接口的特点(理解)
        1.接口中方法全部都是 public abstract 的。
        2.接口中变量全部都是 public static final 的。
        (接口中的数据都是不可变的,接口中的方法都是可改变的)
        3.接口中没有构造方法,不能创建对象。
        4.接口中的所有抽象方法必须在实现类中实现,否则实现类也必须是抽象的。

    D.接口的FAQ(理解)
        接口中都是抽象的。
        1.接口可以实现(implements)接口吗?
            不能,接口中没有可以直接运行的代码,也就是没有具体的实现(implements),因此它不能实现接口。
        2.接口可以继承类或者抽象类吗?
            不能,接口中不能有任何具体的实现。普通类不行,抽象类也不行。因为抽象类可能有具体的实现。
        3.接口可以继承接口吗?
            可以,接口中没有具体的实现,继承下来不会产生冲突。
        4.一个接口可以继承多个接口吗?
            可以,
        5.一个类可以实现(implements)多个接口吗?
            可以
        6.一个类实现(implements)接口和继承类能共存吗?
            可以

    E.两道面试题(理解)
    面试题1:java中有多继承吗?
              在类的继承体系中,存在着单根继承,多层继承。
              在接口的继承体系中,存在这多根继承,多层继承。
    面试题2:为什么类不能多继承,而接口可以多继承。
               因为类中的方法有可能不是抽象的,如果允许多继承就会出现调用的不确定性。可能出现菱形问题。
               因为接口中的方法都是抽象的,即使允许多重继承,也不会出现调用的不确定性。不会出现菱形问题。

    F.继承体系中的三种关系(理解)
        1.子类与父类的关系
             继承关系,extends表示,is-a关系,单重继承,多层继承.
        2.实现类与接口的关系
             实现关系,implements表示,like-a关系,多重实现,多层实现。
        3.子接口与父接口的关系
              继承关系,extends表示,多重继承,多层继承。

    G.接口的一些特点(理解)
        接口是一种契约规范合同。
        接口是对外暴露的规则。
        接口是程序的功能扩展。
        接口的出现降低耦合性。(暂时没学)
        接口可以用来多实现。
        类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
        接口与接口之间可以有多继承关系。

    H.抽象类和接口的关系(记忆)
        相同点:都是不断抽取出来的抽象的概念,都不能创建对象。
                必须是由子类或实现类来创建对象。子类必须实现所有抽象方法。
        不同点:
            A:内部成员不同
              抽象类:
                构造方法:有构造,初始化子类对象使用
                成员方法:有抽象的,有非抽象的
                成员变量:有常量,有变量
               接口:
                构造方法:无。初始子类需要父类构造方法,不需要接口的构造方法,
                       因此没必要提供。
                成员方法:只能是抽象的。默认修饰符:public abstract
                成员变量:只能是常量。  默认修饰符:public static final

            B:继承表现不同:
                 抽象类:
                    一个类只能继承一个抽象类。只能有一个爹
                  接口:
                    一个类可以多实现多个接口。可以有多个大爷
                    一个接口可以继承多个接口。接口可以有多个爹
            C:关系本质不同
                抽象类被继承表示的是:"is a" 的关系,extends关键字
                接口被实现表示的是:"like a" 的关系,implements关键字
            D:实质含义不同:(看情况)
                抽象类在继承体系中体现着子类的共有功能。
                接口在继承体系中体系着实现类的扩展功能。

            E.为啥接口比抽象类好?(扩展)
            增加抽象类可能会改变原有继承体系,如果增加接口,则不会改变原有继承体系。
       
    I.使用接口的例子
        interface Animal{
               /* Animal(){
                   //自己不能创建对象。用不到
                   //子类型构造对象的时候也用不到。
                }
                */
                public static final int age=10;
                public abstract void eat();//有静态吗?没有
                public abstract void sleep();
                public abstract void run();
        }
        //implements实现  Dog类是Animal接口的实现类
        class Dog extends Object implements Animal{
            Dog(){
                    super();
                }
                public  void eat(){
                    System.out.println("狗吃骨头");
                }
                public  void sleep(){
                    System.out.println("狗天天睡");
                }
                public  void run(){
                    System.out.println("人模狗样");
                }
        }
        class Cat implements Animal{

                public  void eat(){
                    System.out.println("猫吃鱼");
                }
                public  void sleep(){
                    System.out.println("猫白天睡");
                
                }
                public  void run(){
                    System.out.println("人模猫样");
                }
        }

        class InterFaceDemo {
            public static void main(String[] args) {
                Dog d=new Dog();
                d.eat();
                d.run();
                d.sleep();
                Cat c=new Cat();
                c.eat();
                c.run();
                c.sleep();
            }
        }


    3.2适配器模式    
                /*
        interface Inter{
            public abstract void show1();
            public abstract void show2();
            public abstract void show3();
            public abstract void show4();
        }
        class InterImpl1 implements Inter{
            public void show1(){
                //第一实现类只知道,第一show1()的具体实现
                System.out.println("InterImpl1--> show1()");
            }
            public void show2(){}//空实现
            public void show3(){}
            public void show4(){}

        }
        class InterImpl2 implements Inter{
            public void show1(){}//空实现    
            public void show2(){}
            public void show3(){
                //第二个实现类只知道,show3()这个方法的具体实现
                System.out.println("InterImpl2--> show3()");
            }
            public void show4(){}
        }
            存在大量重复代码怎么办?
            如果接口中有四十个抽象方法,难道没一个实现类都要实现四十个方法吗?
            为啥有大量的空实现。因为实现类中存在大量的抽象方法,必须要全部实现。
            如果没有抽象方法,就不需要空实现了。
            怎么能保证没有抽象方法呢?
        */
        //适配器模式,用一个类去实现接口的所有方法,其他类作为适配器的子类。
        interface Inter{
            public abstract void show1();
            public abstract void show2();
            public abstract void show3();
            public abstract void show4();
        }
        //适配器,抽象类中可以没有抽象方法,抽象类的本质是不让类创建对象。
        abstract class  Adapter implements Inter{
            /*
            此处不可以用私有构造方法实现,只能将类变为抽象类
            private Adapter(){
            }
            */
            //一个类实现接口中全部的方法,而且全部是空实现
            public  void show1(){}
            public  void show2(){}
            public  void show3(){}
            public  void show4(){}
        }
        //原来实现接口的类,改变成Adapter类的子类
        class InterImpl1 extends Adapter{
            /*
            辅助分析为什么只能是抽象类,不能是私有构造方法
            InterImpl1(){
              super();
            }
            */
            public void show1(){
                //第一实现类只知道,第一show1()的具体实现
                System.out.println("InterImpl1--> show1()");
            }
        }
        class InterImpl2 extends Adapter{
            public void show3(){
                //第二个实现类只知道,show3()这个方法的具体实现
                System.out.println("InterImpl2--> show3()");
            }
        }
        class AdapterDemo {
            public static void main(String[] args) {
                InterImpl1 i1=new InterImpl1();
                i1.show2();
                /*无意义,压根就不让你创建Adapter的对象
                Adapter a=new Adapter();
                a.show1();
                a.show2();
                a.show3();
                a.show4();
                */
            }
        }


4.    关键字总结和访问修饰符
    private
       1.私有变量:该变量只能在本类中使用。
       2.私有方法:该方法只能在本类中使用。
    abstract
       1.抽象类,不能创建对象的类。
       2.抽象方法,没有方法体的方法。
    static (对象能找到它,它找不到对象)
       1.静态方法:和类相关的方法。
       2.静态变量:和类相关的变量。
    final
       1.final 变量 :变量的值不能修改,常量。
       2.final 方法 : 方法不能被修改(可以继承,不能重写)
       3.final 类   : 类不能被修改(不能被继承)
       


        
    四种最大访问权限
       包外可以访问        public
       包子类外可以访问    protected
       包内可以访问        不写(default不是关键字,不写)
       类内可以访问        private


0 0
原创粉丝点击