Day08 --代码块 继承 重写 this和super final关键字

来源:互联网 发布:好看的输入法软件 编辑:程序博客网 时间:2024/05/19 16:34
 a.
    代码块
        在java中,用{}扩起来的叫做代码块。
    
    分类
        根据位置和声明的不同,可分为局部(方法中的),构造,静态,同步代码块(多线程再讲)
    
    代码块的应用
        局部代码块 [方法中]
            * 在方法中出现的。随着实例化对象的创建而存在,用来限制变量生命周期,及早释放,可提高代码利用率。
                * 跟for循环类似,int i的访问范围一样。
    
        构造代码块 [类中方法外](又叫初始化块)
            * 在类中方法外出现。每创建一次对象,都要执行一次构造代码块,并且优先于构造方法前先被执行。
                * 且多个构造方法中相同的代码放在一起,每次调用都有执行,每次创造对象后,先执行构造代码块,再构造方法,再普通方法。
                
        静态代码块 [优先于主方法前先被执行]
            * 在类中方法外出现,加上static来做修饰,用于给类进行初始化的,在类加载的时候执行,有且只执行一次。
                * 作用:
                    * 给类做初始化用的,一般用于加载驱动(驱动也加载一次)。
                
                * 因为被static修饰的,所以静态代码块是随着类的加载而加载的,当在类加载时,static静态代码块就会被执行,因为类只加载一次,所以static一只加载一次。
                * 无论创建多少个对象,static静态代码块都执行一次。
                * 一般用于加载驱动的。

作业题一:
1、代码块是什么,分为哪几类,各自有什么特点?
含义:
    * 在java中用{}扩起来的就称为代码块。
代码块分类:
    * 静态代码块
    * 局部代码块
    * 构造代码块
    * 同步代码块
各自特点:
    * 静态代码块,在类中方法外,用 static 来做修饰,用于给类进行初始化用的,是随着.class 字节码文件的加载而加载的,优先于主方法先存在,随着类的消失而消失,一般用于加载驱动,且只能执行一次。
    * 局部代码块,在方法中出现,用于限定变量的生命周期,可用于提高内存的利用率。
    * 构造代码块,在类中方法外,多个构造方法相同的代码存放在一起,每次再调用构造方法前执行。
    * 同步代码块,多线程再讲。




        注意事项:
            局部/构造/静态/代码块的执行顺序:
            静态 > 局部 > 构造


例子:
    参考:G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\Demo1_代码块_局部代码块.java 



    静态代码块,构造代码块,构造方法的执行流程?
            静态代码块
                * 当jvm加载.class字节码文件时,给类进行初始化的,且只执行一次。
            构造代码块
                * 在构造方法之前被执行。
            构造方法
                * 随着实例化对象的创建而执行,且每次创建对象,都执行一次构造方法,随着对象的释放而消失。 


作业题二:
2、子父类都有静态代码块、构造代码块、构造方法,那么他们六者之间的执行流程是什么?
分析:    
    1) 因为子继承父,所以先执行父类的字节码文件,因为静态代码块是随着类的加载而加载的,所以第一步先执行:父类的静态代码块。
    2)父类的静态代码块执行完成后,子类的字节码文件也同样加载到内存,所以第二步是:子类的静态代码块。
    3)因为new的是子类的对象,又因为构造代码块是在构造方法之前执行的,且二者存在继承关系,所以第三步执行的是:父类的构造代码块。
    4)执行完第三步:父类构造代码块后,紧接着执行第四步:父类的构造方法。
    5)当父类的构造方法执行完后,开始执行子类的构造方法,因为构造代码块是在构造方法前执行的,所以第五步执行:子类的构造代码块。
    6)当子类的构造代码块执行完后,开始执行子类的构造方法。
所以顺序是:
    1)父类静态代码块
    2)子类静态代码块
    3)父类构造代码块
    4)父类构造方法
    5)子类构造代码块
    6)子类构造方法


    代码块面试题
        分析程序中的代码的执行顺序?

例子:
    根据 静态 > 局部 > 构造这个顺序来分析:
    参考:G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\Demo2_Student_构造代码块面试题.java




b.    
    继承
        概念
            * extends 表示关键字,用于让类与类之间产生关系,只存在于子父类当中。(子继承父,不可父继承子)
            * 他们是一种满足 is a的一种关系,如猫是动物的一种。
            * java中只支持单继承,不支持多继承,但支持多实现和多层继承。
                * 多层继承:子 继承 父, 父 继承 爷 ,子 继承 爷(子继承爷就是多层继承)


        好处
            * 提高代码复用性    (父类有了,子类就不需要再写了,继承即可)
            * 提高代码维护性    (新添加属性,只要在父类中添加了,其他子类也就都有了)
            * 让类与类之间产生关系,这是多态的前提    (多态:即多种形态) 因为要:父类有用指向子类对象。        
        弊端
            * 增强了代码的耦合性,因为优秀的代码都是围绕着 “高内聚,低耦合”的原则去开发的。
           (耦合性:两个类过分紧密,父类有什么,子类就必须有什么。)



    开发原则
        * 高内聚,低耦合(使用装饰者模式,就能降低耦合性)
        
        * 内聚:自己完成某件事情的能力,耦合性低,之间能完成是事情不求他人。【公司离开你,还能活】
        * 耦合:类与类之间的关系。【你离开公司,就不能活】
        
        高内聚:自己能完成的事情,自己做。
        低耦合:合作式开发,但是要主次分明。
    
    p.s.
        子类只能访问父类中非私有的成员(属性和方法)。    
        子类无法继承父类中私有的内容。
        父类怎么来的? 共性内容不断向上抽象来的。
    
    p.s.贝贝2017/8/19 1:07:35 


作业题三:    
3、继承的好处、弊端分别是什么?
好处:
    * 提高代码复用性。
    * 提高代码维护性。
    * 让类与类之间产生关系,是多态的前提。
弊端:
    增强了代码之间的耦合性,优秀的代码开发一直遵循的是一种 “高内聚,低耦合” 的一种开发规则。
        高内聚:自己完成的事情,一般不求他人(在开发的意思是,本类能完成的功能尽量在本类完成,即本类完成功能的能力度。)
        低耦合:合作式开发,但是要分清主次关系(一般开发规则有:分模块开发 和 分功能开发。)


​    
装饰者模式
    好处:降低耦合性,被装饰的类与装饰的类无关。
    代码实现:
        1. 获取被装饰类的引用
        2. 在装饰类的构造方法中传入被装饰类的对象
        3. 对原有功能进行升级

例        
        class Demo2_装饰者模式 {
            public static void main(String[] args) {
                    
                    HmStudent hm = new HmStudent(new Student());
                    hm.name="哈哈";
                    hm.age=22;
                    hm.study();
                    System.out.println(hm.name+"..."+hm.age);
                }
            }


            //黑马学生 继承 学生类  且 实现 方法Coder类的接口。 
            //在实现接口类中,完成具体的方法实现。
            class HmStudent  extends Student implements Coder{
                //1. 获取被装饰类的引用
                private Student s;
            
                //2、在装饰类的构造方法中传入被装饰类的对象
                public HmStudent(Student s){
                    this.s = s;
                }
                
                public void code(){
                    //3. 对原有功能进行升级        
                }
                
                //在实现接口类中,完成具体的方法实现
                public void study(){
                    System.out.println("程序员敲代码.");
                }
                
            }
                
            //接口        接口中定义的都是方法,且都是没有方法体的方法。
            interface Coder{
                public void study();
            }
            
            class Student {
                String name;
                int age;
            }


    继承特点    
        * java中只支持单继承,不支持多继承,但支持多实现(即实现接口)。
            * 但有些语言可支持多继承,如: a类 extends c类,d类,e类...
        原因?
            * 因为多继承容易出问题,如果两个父类中有相同的方法,子类就不知道该具体调用哪一个方法了。
            * 这种机制就换来了另一种安全的方式来体现,即多态。            
    
        * java中存在多层继承的关系(即继承体系)
            * 子 extends 父 
            * 父 extends 爷
            * 子 extends 爷
            
        * 由继承的特点可看出:
            * 如果想用这个体系的【所有功能】, 看【最底层(儿子类)的类去创建对象】【即子类是用于扩展的功能】
            * 如果想用这个体系的【共性功能】, 看【最顶层(爷爷类)的类,即最先继承的类】
    
    Java中继承的特点
        * java中只支持单继承,不支持多继承,但支持多实现和多层继承。
        * 当创建对象时:
            如果是想要其共性部分,就去找顶层(即父类)
            如果想要知道功能性最全的,就去找底层(即子类)
    
    p.s.
        子类中所有的构造函数默认都会访问父类中的空参构造函数,因为每一个构造函数的第一行都有一个默认的super语句,去访问父类的空参构造,即使一个普通类第一行也有一个super语句,因为他会去访问Object类。
        
        为什么子类实例化的时候要去访问父类中的构造函数?
        因为子类继承父类,获取到父类中的内容,所以在使用父类内容之前,要先看看父类是如何自己的内容进行初始化的。
    
        1. 当父类中没有空参构造时,子类的构造函数必须通过this或super语句指定要访问的构造函数。
        2. 子类构造函数中如果使用this调用本类的构造函数,那么默认的super就没有了,因为super和this不同同时定义在的第一行,所以只能存在一个,但是可以保证的是,子类中肯定有其他的构造繁琐去访问父类的构造函数
        3. super必须存在子类的构造函数的第一行,因为父类的初始化动作要先完成。


​        


作业题四:    
4、Java中继承的特点是什么?
特点:
    * Java只支持单继承,不支持多继承,但支持多实现和多层继承。
        多实现:一个类可以实现多个接口。接口:后面说。
        多层继承:子继承父,父继承爷,子继承爷,存在这种关系后,子继承爷就是多层继承了。
当创建对象时,
    如果想要其共性部分功能,就找顶层(父类,即创建父类对象)。
    如果想要其全部功能,就找底层(子类,即创建子类对象)。


例子
class Demo3_Extends继承的特点 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in); //in表示键盘录入的意思。
    
        DemoC c = new DemoC();
        c.show(); //结果是:DemoB 
    }
}

//最顶层的类 即爷爷类 有最完善的【共性功能】
//爷爷类
class DemoA {
    public void show(){
        System.out.println("DemoA ");
    }
}

//父亲类
class DemoB extends DemoA {
    public void show(){
        System.out.println("DemoB ");
    }
}


//最底层的类  即儿子类 有最完善的【全部功能】
//儿子类
class DemoC extends DemoB {
​    
}
//不能让C类即去继承A类,也继承B类,这不符合Java对于继承的规定,
//只能【多层继承】,即通过 B extends A, 再让C extends B 来完成对A类和B类所有功能的继承。

//不能多继承的原因?有安全隐患,如果让C类同时继承A,B类,当创建C类对象时,就不知道该具体调用AB中哪个同样的show方法了。
//当C类去 extends B类(B 已经extends A了)时,创建C类对象后,c调用show()方法, 输出的结果是 :DemoB,因为 B extends A时,b中有同样有show方法,就将A中的show方法给覆盖了,所以打印c.show(),结果自然是DemoB。

    继承的注意事项和什么时候去使用继承
        注意事项:
            * 子类只能继承父类所有(非)私有的成员[即成员方法和成员变量],因为私有成员只能在本类使用。 【但想继承也可以,通过暴力反射完成 最后一天课程说】            
            * 子类不能去继承父类中构造方法,但是可以通过super来访问父类的构造方法。
                * 子类不能继承父类的构造方法?因为两个类的类名不同,且构造方法是在创建对象的时候使用的,如果继承了,系统在创建对象后,就不知道具体该调用哪个构造方法了。
    
            * 不能为了部分功能去继承。
                *   * 项目经理 姓名 工号 工资 奖金
                    * 程序员    姓名 工号 工资    
                    * 【只能向上抽取出来一个员工类,放共性功能,让项目经理类和程序员类都去继承该员工类即可】
                     
        什么时候使用继承:
            不能为了单独继承而继承,他们之间是一种 is a的关系,只有满足了这种情况才考虑去使用继承。
    
        即:
            动物
                猫
                狗
                    (猫是动物的一种  狗是动物的一种) 即 is a 的关系。
            水果
                苹果
                香蕉
                桃子
                    (苹果是水果的一种  香蕉是水果的一种)即 is a 的关系。
    
    采用假设法:
            如果有两个类A,B 只有满足A是B的一种,或B是A的一种的时候,才考虑使用继承。



    继承中局部变量的关系
        情况一:
            * 不同名的变量
                * 在子父类中出现不同名变量,结果都输出。
                 
        情况二:
            * 同名变量
                * 在子父类中出现了同名变量,就采用就近原则,即子类当中有,就使用子类的。
【子父类中出现同名变量,只在讲课中有,开发中是不会出现的。因为子类继承父类,就是为了让子类去使用父
类中的成员,如果子类中都有了父类中同名的成员变量,就没有任何意义了。】




作业题五:
5、Java中继承的注意事项是什么?我们什么时候使用继承? 继承中局部变量的关系?
注意事项:
    * 子类只能继承父类非私有的成员,如果子类或其他想要访问私有成员,必须使用get()方法进行访问。

什么时候使用继承:
    * 不能为了部分功能去实现继承,只有他们满足一种 “is a” 的关系(苹果是水果的一种)时,才考虑使用继承,一般两个类或以上的类都满足 “is a” 的关系时,就向上抽取出父类,即公共类。
    注意;子类不能继承父类的构造方法,只能通过super关键字去调用父类的构造方法,不然jvm无法识别使用是子类的构造方法还是父类的构造方法。
        如:
            子类:
                名字:苹果,颜色:红,功能(方法):补充营养。
                名字:香蕉,颜色:黄,功能(方法):利肠道。
        因为存在多个重名属性,即向上抽取父类:
            父类:
                * 相同属性:名字 和 颜色。
                * 方法:功能(食用保持身体健康)。
    
        且在子类中重写方法,完成其特有的功能即:
                                    * 子类苹果:补充营养。
                                    * 子类香蕉:利肠道。

继承中局部变量的关系:
    同名变量名称:
            采用就近原则,谁离子类进,就使用哪个,即就近原则。
    异同变量名称:
            如果是异同变量名称,结果都输出。

c.
    this和super的区别和使用
        this
            * 代表当前对象的引用,即谁来使用我,我就代表谁。
        super
            * 代表当前对象父类的引用,即子类继承父类后,想要去使用父类的成员时,可
            * 使用super。
        p.s.
        子父类中,成员的特点体现:
            1)成员变量:
                * 在本类中成员变量和局部变量可以用this来区分, this表示成员变量。因为局部变量一般在方法里或方法声明上。
                * 当子父类中出现同名成员变量时,可以用super来区分父类。
                
            2)成员方法:
                * 当子父类中出现成员方法一模一样的情况的时候,会运行子类中的方
                  法,这种现象被称为:覆盖操作(重写)。这是方法在子父类中的特性。
                * 在子类覆盖(重写)父类方法后,还想继续使用被覆盖的父类方法时,可以通过super.方法名()来获取。
            
            方法的两个特性:
                1) 重载,只出现在本类中,即overload。
                2)  重写,出现在子父类当中,即override。 有道词典翻译: vt. 推翻;不顾;践踏

​            



        this和super的使用区别 (3种区别)
            * 调用成员变量
                    * this.成员变量   即可调用本类的成员变量,也可调用父类的成员变量。
                            * 前提是本类当中没有,才能去使用父类的,因为他们存在继承关系。
                            
                    * super.成员变量  只能调用父类中的成员变量。
            * 调用构造方法
                    * this(语句)  只能调用本类的构造方法
                    * super(语句) 只能调用父类的构造方法
    
            * 调用成员方法
                    * this.成员方法()  即可调用本类的成员方法,也可调用父类的成员方法
                    * super.成员方法() 只能调用父类的成员方法


    继承中构造方法的关系(继承中构造方法的执行流程)
        * 子类中所有的构造方法默认都会去访问父类中的空参构造。【前提:必须是继承关系】
        * 为什么?
            * 因为子类继承父类中的数据,还可能会去使用到父类中的数据,所以子类在完成初始化之前,一定会
              去完成对父类数据的初始化。    
    
        其实
            每个构造方法的第一句默认都是调用:super()。 Object类是最顶层的父类,所有的类都继承他,自定义的类也一样继承他。


            子类中的构造方法都有一个默认的super(),去访问父类的空参构造。
        原因?
            因为子类继承父类的属性,很可能会去访问父类中属性的数据,所以要必须先对这些属性进行初始化,才能去访问父类的构造方法。


    继承中构造方法的注意事项
        父类没有无参构造,子类该怎么办?
            * super解决  可在在子类中,调用父类中的无参构造。(也能调用父类的有参构造)
            * this解决   可在在子类中,调用本类的有参构造。 
            
        【注意】
            super()或this必须出现在构造方法的第一条语句上,不能同时出现。
            但是在普通方法中this.父类方法()和 super.父类方法() 可以不用放在第一行。
            具体可参考:G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\day08_最新作业代码\Work3_存在继承关系的猫咪_狗狗类.java 中的Dog lookHome()方法里的写法。

作业题六
6、this关键字和super关键字分别代表什么,以及他们各自的作用分别是什么?
分别代表:
    this  代表当前对象的引用,谁使用我,我就代表谁,即哪个对象使用this,this就代表哪个对象。
    super 代表当前对象父类的引用,用于在子类中去访问父类的成员及构造。

this 和 super 的区别:(3种)
    * 调用成员变量
            this  既能调用父类的成员变量,也能调用子类的成员变量。
            super 只能调用父类的成员变量。
    * 调用成员方法
            this.成员方法   既能调用父类成员方法,也能调用子类成员方法。
            super.成员方法  只能调用父类的成员方法
    * 调用构造方法
            this  只能调用子类的构造方法
            super 只能调用父类的构造方法

作业题八                
(没有7)8、继承中构造方法的执行流程是什么?
    执行顺序:
        先执行父类中的构造方法,再执行子类中的构造方法。
作业题九
9、为什么子类中所有的构造方法默认都会访问父类的空参构造?
   假如父类没有无参构造方法,子类应该怎么办?
    答:
        问题一:因为在子类对象在访问父类数据前,用于对父类数据进行初始化的。
        问题二:如果父类中没有无参构造,可在子类中使用super();来访问父类的有参构造,或使用this();来调用本类的其他构造。

作业题十
10、super关键字和this关键字可以在构造方法中共存吗?
        额可以,只能放在第一行,如果是其他普遍方法,super或this可以不用放在第一行。
        子类{
            super(); //调用的是父类的构造。
            this.setName(name); //因为存在继承关系,所以也就相当于调用子类的set方法
        }



继承中的面试题
​        
看程序写结果1
        class Fu{
            public int num = 10;
            public Fu(){
                System.out.println("fu");
            }
        }
        class Zi extends Fu{
            public int num = 20;
            public Zi(){
                super();    //有个隐藏的super();每个构造方法中都有一个默认的super,去调用父类的完成构造方法
                System.out.println("zi"); // num=20;
    
            }
            public void show(){
                int num = 30;
                System.out.println(num);  //采用就近原则    即30    
                System.out.println(this.num); //this是用于区分重名的成员变量和局部变量,这里的this表示成员变量,即20     
                System.out.println(super.num);  //super调用是的父类的成员变量,即10
            }
        }
        class Test1_Extends {
            public static void main(String[] args) {
                Zi z = new Zi();
                z.show();
            }
        }
    
        执行顺序:
            fu  1)首先Zi(),会去调用zi的无参构造,因为zi的无参构造中有super(),所以先去调用父类的无参构造,即fu。
            zi  2)输出fu后,zi()中的无参构造里还有一个语句,即:zi。
            30  3)接着调用z的show()方法, 第一个输出语句num,即采用就近原则,所以num=30。
            20  4)this.num 是访问重名的成员变量和局部变量时,用来访问成员变量用的,即:this.num=20。
            10  5)super.num 中的super是访问父类的,所以super.num = 10;


​            

看程序写结果2
    class Fu {
        static {
            System.out.println("静态代码块Fu");
        }
    
        {
            System.out.println("构造代码块Fu");
        }
    
        public Fu() {
            System.out.println("构造方法Fu");
        }
    }
    
    class Zi extends Fu {
        static {
            System.out.println("静态代码块Zi");
        }
    
        {
            System.out.println("构造代码块Zi");
        }
    
        public Zi() {
            System.out.println("构造方法Zi");
        }
    }
    
    Zi z = new Zi(); 
    
    结果:    静态代码块Fu           1)因为创建的是zi()的无参对象,又因为zi继承fu,所以fu类先加载到内存,即 先输出:静态代码块Fu。
            静态代码块Zi        2)又因为创建时zi类的对象,所以zi类也要加载到内存,即输出:静态代码块Zi    
            构造代码块Fu        3)访问zi的无参构造对象时,必须要先访问父类的无参构造,又因为无参构造是在构造代码块后面出现的,所以先输出:构造代码块Fu
            构造方法Fu        4)随着构造代码块的输出后,再输出无参构造。
            构造代码块Zi        5)只有先访问完父类的无参构造时,再能访问子类的无参构造,因为构造代码块时先于构造方法前先执行的,所以先输出:构造代码块Zi
            构造方法Zi        6)构造代码块输出后,才能输出构造方法,所以是:构造方法Zi

老师说法:
        1) jvm调用main方法, 方法都进栈,所以main方法进栈。
        2) 首先遇到Zi z = new Zi(),因为zi类继承父类,所以会先将fu.class和zi.class分别加载到内存,当fu.class加载进内存时,静态代码块也会随着fu.class一起加载, 当zi.class加载进内存时,静态代码块也会随着zi.class一起加载。所以第一个输出:静态代码块Fu  第二个输出:静态代码块Zi
        3) 加载完后,走zi类的构造方法,因为java是分层初始化的(在子类的构造方法中,每个子类中都有一个super),所以先去走父类的构造方法, 但是在执行父类构造时,发现父类有构造代码块,构造代码块是优先于构造方法前先执行的,所以第三个输出的是:构造代码块Fu 第四个输出的是:构造方法Fu。
        4) fu类初始化后,就该子类初始化,所以第五个输出是:构造代码块Zi    第六个输出的是:构造方法Zi


    原则: 
        * 静态代码块是,随着类的加载而加载的。
        * 构造代码块先于构造方法前先被执行。
        
    顺序:
        静态代码块 > 构造代码块 > 构造方法


​    


    继承中成员方法的关系
        --出现的情况:            
            * 不同名方法时:
                * 都能够调用,即可调用父类中的方法, 也能调用子类中的方法
            * 同名方法时:
                * 如果子类定义了父类中重名的方法, 就使用子类中的方法,这种叫【方法的重写或覆盖】
                * 如果还想使用父类中重名的方法的话,可以在子类中重名方法里的
                  第一行使用:super.父类重名成员方法(); 即可完成对父类重名方法的调用。






d.
    方法的重写
        概述
            在子父类中出现了一模一样的方法(返回值类型可以是子父类,面向对象再说)【方法名,返回值相同,参数列表一样理解为方法的重写】
        应用
            当子类需要父类中的功能,而功能的主题子类自己特有的内容时,可以重写父类中的方法,这样既延续了父类功能,也完成了子类的特殊性。如果在子类重名方法中还想使用父类中的重名方法,可以通过super.父类方法();来调用即可,该方法可以不用放在第一行,只有在构造方法中super才只能放在第一行。
    
        为什么使用继承和重写
            主要是为了系统的升级和功能的扩展。

【注意:只有在构造方法中super只能放在第一行,其他方法中使用super可以不再第一行】

【Java采用的是Unicode的编码,Unicode的编码容纳了世界上的所有语言,所以支持中文编写程序,但一般建议不使用中文。】


例子:
    G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\02_继承\Demo6_方法的重写.java

​    

    重写注意事项 (4个)
        1. 子类不能继承父类私有的方法
            * 因为父类中的私有方法,无法被其他类所继承。
        2. 子类重写父类时,访问权限不能低于父类(即子类>=父类的访问权限) (public最大)
            * 因为定义子类是希望子类比父类更加强大。如果子类权限比父类越来越小,最终会导致子类无法被使用(即子类无法被当成父类被其他类所继承)。
            * 最好权限修饰符一致,如果父类没有权限修饰符,子类也可不写
        3. 父类中的静态方法,子类也必须通过静态方法来实现重写
            * 静态只能覆盖静态,非静态不能覆盖静态,且静态也不能覆盖非静态,因为jvm无法识别去调用具体哪个方法 其实这种形式不属于方法的重写,多态中再具体解释。
        4. 子类重写父类方法,最好声明一模一样


方法重写面试题
over:之前,理解为再此之前。
ride:推翻
load:装填 
override: 再此之前推翻原先的,即重写。 只能出现子父类中
overload: 再此之前装填更多的,即重载。 只能出现本类中

    重载(overload[装填])和重写(override[推翻])的区别 (2个)
        * overload(重载): 只能在本类中,出现了方法名相同,与返回值类型无关,只看参数列表的形式。
        * override(重写): 只能出现子父类中,出现了方法名相同,且与返回值类型有关的。
        
        重载:本类中出现方法名相同,且与返回类型无关,只看参数列表的方法。
        重写:子类中出现了父类中一模一样的方法,且与返回值类型有关,返回值类型一致的或是父类。


        * overload(重载) 能改变返回值类型,方法名相同,与返回值类型无关,只看参数列表。     
        * override(重写)不能改变返回值类型(方法名和参数列表必须相同,多态再具体说明) 返回值类型可以是父类。
        
    p.s.
    方法的两个特性:
            1) 重载,只出现在本类中,  即overload。
            2)  重写,出现在子父类当中,即override。


​    
子类调用方法的顺序:
    先找本类,再找父类。(就近原则)

    p.s.
    什么时候使用重写重载?
        当子类需要父类功能,当功能主体是子类特有的内容是,就可以覆盖父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。
    
    * 父类中私有成员不能被重写。
    * 父类中static的方法不能被重写。
    * 重写时,子类方法权限必须大于或等于父类方法权限。


作业题十一
11、Overload和Override的区别是什么?方法重载能改变返回值类型吗?
        overload 是重载,只能出现在本类当中,规则:方法名相同,与返回值类型无关,只看参数类别的一种形式,且能改变返回值类型。
        override 是重写,只能出现在子父类当中,在继承关系中,出现了子父类规一模一样的方法就是重写,规则:必须方法名相同,返回值类型相同,参数列表也相同的一种形式,且无法改变返回值类型。
    
        overload 重载 可以改变返回值类型。
        orveride 重写 无法改变返回值类型。




    继承中的细节问题
案例1:    

A:案例演示 
  * 使用继承后的学生和老师案例
     * 使用继承后,增强了代码复用性,减少了代码的冗余。

       * 分析:
         * a.首先将两者的共性抽取出来,创建一个共性父类Person,封装其共性属性,完成共性内容。
         * b.然后创建子类学生和老师,让他们去继承Person父类。
         * c.然后在学生和老师中完成特有的功能。
         * d.两种赋值方式:setXXX() 和 new对象实际传参。

         this.getName()  是子类继承了父类,相当于本类中也有了this.name = name;
         super.getName() 是子类去直接调用了父类中的方法。
         getName() 是隐藏了this,其实还是this.getName();


该例子必须去看看。
地址:
G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\02_继承\Test2_使用继承后的学生和老师案例.java

案例2:

    * A:猫狗案例分析
    * B:案例演示
        * 猫狗案例继承版
        * 属性:毛的颜色,腿的个数
        * 行为:吃饭
        * 猫特有行为:抓老鼠catchMouse
        * 狗特有行为:看家lookHome
    
    分析:
        1. 将两者共性内容,抽取出来放入父类Animal中,完成共性属性和内容。
        2. 再创建子类猫,狗分别去继承父类Animal
        3. 再在子类中完成其特性部分。


        子类中有参构造方法的写法:
            *可通过super(name, age); 去调用父类中的有参构造。super是本类对象父类的引用。


        子类中属性的访问可使用3种形式:
            * getName();    该方法隐藏了this, 因为存在继承关系,所以访问的相当于也是本类的 this.name = name;
            * this.name();  因为存在继承关系,所以访问的相当于也是本类的 this.name = name;
            * super.name(); super是本类对象父类的引用,所以直接就是调用父类中的getName()的方法。

地址:
G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\02_继承\Test3_猫狗案例分析和实现及测试.java


​    
​        

e.
    final关键字
        概述
            final是关键字,翻译为 "最终",只要被final修饰的,都不能修改和继承。
        应用
            * 修饰类时,类不能被继承,但能继承其他类。
                *  如: public final class Animal{}
                
            * 修饰方法时,方法不能被重写。
                * public final void method(){}
            
            * 修饰成员变量时,变量变常量,要求所有字母大写,多个单词用下滑线隔开,【且只能被赋值一次,且必须赋初始化值,不能为空。】
                *  final int AGE = 4; (不能被修改的常量)
                *  public static final int LEG =3; (静态且不能改变的常量)
                *  final修饰的变量叫常量,所有字母都大写,一般和public static 一起被使
                   用,即:public static final String NAME="张三";
例子:G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\04_final\Demo1_final_关键字概述.java


作业题十二
12、final关键字可以做什么,有什么特点?
        含义:
            final 是关键字,被翻译为 最终,可用于修饰类,变量,方法。
        特点:
            修饰类时,该类不能被继承,但可以继承其他类。
            修饰变量时,变量变常量,必须初始化,不能为空和只能被赋值一次,即所有字母大写,如果存在多个单词,用下滑写将每个单词隔开,一般和 public static 一起使用,即 public static int AGE =7;。
            修饰方法时,该方法不能被其他类重写。

作业题十三
13、final修饰局部变量时,有什么特点?
        有两种情况:
            当局部变量是 基本数据类型:其值不能被改变。
                         引用数据类型:地址值不能被改变,但对象中的属性值能被改变。




        注意事项    
A:案例演示
方法内部或者方法声明上都演示一下(了解)
修饰局部变量
  * 基本数据类型: 值不能被修改。
  * 引用数据类型: 只是地址值不能被改变,但对象的属性值是可以改变。

  //方法内部
      基本数据类型:
          final int a = 3;
          a=10;
          sop(a);//3  因为final修饰基本数据类型,其值不变。


        引用数据类型:
            final Person p = new Person("呵呵",7);
            p = new Person("哈哈", 13); //直接报错,因为被final修饰的对象,即就是地址值,不能被重新赋予一个新的地址值。
            
            但可以:
            p.setName("楚乔");
            p.setAge(6);
            sop(name, age); //结果:楚乔 6 ,因为被final修饰的引用数据类型,其对象的属性值是可以改变的,但地址值是不能改变的。
            
    //方法声明上
            method(5); //5
            method(6); //6 最终值改变,因为每个方法都是调用完后,都弹栈,下一个方法进来是新的方法即新的属性值,所以值是改变的。


例子:
G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\04_final\Demo2_final_局部变量的注意事项.java    


    final修饰变量的初始化时机
        * 必须显示初始化。
        * 在对象的构造方法完毕前完成初始化即可。

例子:
G:\CSDN_Android_\Code\day08 代码块 继承 重写 this和super final关键字\04_final\Demo3_final_修饰变量的初始化时机.java

    p.s.
        为什么要用final来修饰变量,其实在程序中如果有一个数据是固定的,那么直接使用这个数据就可以了,但是这样的阅读性差,所以要给这个数据起个名字,而且这个变量名称的值不能任意改变,所以要加上final来固定。
        写法: 常量所有字母大写,多个单词,中间用_来隔开。


阅读全文
0 0
原创粉丝点击