• 继承进一步使用,以及super关键字


    目标:

    1)掌握子类对象实例化过程

    2)掌握方法覆盖概念和实现。

    3)掌握super关键字的作用。

    一,子类对象实例化过程

    子类对象在实例化之前,必须先调用父类中的构造方法,再调用子类中的构造方法。

    class Person{                    // 定义Person类
        private String name ;        // 定义name属性
        private int age ;            // 定义age属性
        public Person(){
            System.out.println("父类Person中的构造。") ;
        }
        public void setName(String name){
            this.name = name;    
        }
        public void setAge(int age){
            this.age = age ;
        }
        public String getName(){
            return this.name ;
        }
        public int getAge(){
            return this.age ;
        }
    };
    class Student extends Person{                    // 定义Student类
        private String school ;        // 定义school属性
        public Student(){
            super() ;    // 默认隐藏
            System.out.println("子类Student中的构造。") ;
        }
        public void setSchool(String school){
            this.school = school ;
        }
        public String getSchool(){
            return this.school ;
        }
    
    };
    public class InstanceDemo{
        public static void main(String arsg[]){
            Student stu = new Student()    ;// 实例化子类对象
            stu.setName("张三") ;    // 此方法在Student类中没有明确定义
            stu.setAge(30) ;
            stu.setSchool("清华大学") ;
            System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge() + ",学校:" + stu.getSchool() ) ;
        }
    };

    运行结果:

    父类Person中的构造。
    子类Student中的构造。
    姓名:张三,年龄:30,学校:清华大学

    在生活中也很好理解,没有父亲就没有孩子。

    实际上,对于子类的构造方法中,隐含了一个“super()”的语句。有时候,也将父类称为超类,所以调用父类构造方法,用super()

    super关键字必须写在构造方法的首行。

    二,方法的复写

    方法覆写就是指:子类中定义了与父类中同名的方法。

    1)但是在方法覆写时必须考虑访问权限,即:被子类覆写的方法,不能拥有比父类更严格的访问权限。

    2)所以,如果在父类中使用public定义的方法,子类的访问权限必须是public,否则无法编译。

    3)private<default<public。

    class Person{        // 定义父类
        void print(){    // 默认的访问权限
            System.out.println("Person --> void print()。") ;
        }
    };
    class Student extends Person{    // 定义继承关系
        public void print(){
            System.out.println("Student --> void print()。") ;
        }
    };
    public class OverrideDemo01{
        public static void main(String args[]){
            Student s = new Student() ;
            s.print() ;
        }
    };
    运行结果:
    Student-->void print()。

    访问权限:

    private:最小的访问权限。

    default:什么都不写,例如:string name;

    public:最大的访问权限。

    以下是访问权限出问题的错误操作。

    package methoud;
    class Person{        // 定义父类
        public void print(){    // public的访问权限
            System.out.println("Person --> void print()。") ;
        }
    };
    class Student extends Person{    // 定义继承关系
         void print(){    // 错误的,降低了访问权限
            System.out.println("Student --> void print()。") ;
        }
    };
    public class ThisDemo06{
        public static void main(String args[]){
            Student s = new Student() ;
            s.print() ;
        }
    };

    由于子类的访问权限default小于public,所以编译通过不了。

    从之前正确操作可以看出,如果子类将父类的方法覆写了,调用的时候,肯定是调用被覆写过的方法,那么如果非要调用父类的方法。

    通过“super”关键字可以完成功能,super关键字可以从子类访问父类的内容。

    如果要访问被覆写过的方法的方法:super.方法();

    例如:

    class Person{        // 定义父类
        void print(){    // 默认的访问权限
            System.out.println("Person --> void print()。") ;
        }
    };
    class Student extends Person{    // 定义继承关系
        public void print(){
            super.print() ;    // 访问父类中被子类覆写过的方法
            System.out.println("Student --> void print()。") ;
        }
    };
    public class OverrideDemo03{
        public static void main(String args[]){
            Student s = new Student() ;
            s.print() ;
        }
    };
    运行结果:
    Person --> void print()。

    Student --> void print()。

    如果要使用“super”不一定非要在方法覆写之后使用,也可以明确表示某个方法是从父类中继承而来的。

    使用super只是更加明确的说直接从父类中寻找,就不从子类找了。因为没有super调用方法,首先从子类寻找,如果子类没有才到父类寻找。

    例如:如果上面那个例子中super.print()把super去掉,就会造成无限期循环递归,自己调用自己

    三,问题:

    如果父类中使用private关键字声明一个方法,那么在子类中使用default权限算是扩大权限,覆写吗?

    答案是:NO,不算覆写。

    正常覆写:

    class Person{        // 定义父类
        void print(){    // 默认的访问权限
            System.out.println("Person --> void print()。") ;
        }
        public void fun(){    // 定义一个fun方法
            this.print() ;    // 调用print()方法
        }
    };
    class Student extends Person{    // 定义继承关系
        void print(){    // 覆写父类中的方法
            System.out.println("Student --> void print()。") ;
        }
    };
    public class OverrideDemo04{
        public static void main(String args[]){
            Student s = new Student() ;
            s.fun() ;
        }
    };
    运行结果:

      Student --> void print()。

    这里因为正常覆写,所以直接调用了子类中的覆写方法。

    错误的覆写:

    package methoud;
    class Person{        // 定义父类
        private void print(){    // private的访问权限
            System.out.println("Person --> void print()。") ;
        }
        public void fun(){    // 定义一个fun方法
            this.print() ;    // 调用print()方法
        }
    };
    class Student extends Person{    // 定义继承关系
        void print(){    // 覆写父类中的方法
            System.out.println("Student --> void print()。") ;
        }
    };
    public class ThisDemo06{
        public static void main(String args[]){
            Student s = new Student() ;
            s.fun() ;
        }
    };
    运行结果:
    Person-->void print();

    可见,这里并没有调用子类中的“覆写”方法,而是调用父类中默认的方法。说明这里并没有达到覆写的作用,子类中的方法其实是另外定义了一个方法。

    这点需要注意!

    四,属性的覆盖。

    覆盖,就是指子类中声明了父类中同名的属性。

    class Person{        // 定义父类
        public String info = "MLDN" ;    // 定义一个公共属性
    };
    class Student extends Person{    // 定义继承关系
        public String info = "LXH" ;    // 定义了一个与父类中属性名称一致的属性
        void print(){    // 覆写父类中的方法
            System.out.println("父类中的属性:" + super.info) ;
            System.out.println("子类中的属性:" + this.info) ;
        }
    };
    public class OverrideDemo05{
        public static void main(String args[]){
            Student s = new Student() ;
            s.print() ;
        }
    };

    可见,要使用被覆盖的父类中的属性,需要使用super关键字。

    五,方法覆盖与重载的区别

    六,super关键字

    super表示的是从子类调用父类中的指定操作。例如调用属性,方法,构造等等。

    因为在子类实例化的时候,会默认调用父类中的无参数构造方法(“super()”)。如果想调用有参构造方法,则必须在子类中明确声明。

    class Person{                    // 定义Person类
        private String name ;        // 定义name属性
        private int age ;            // 定义age属性
        public Person(String name,int age){
            this.setName(name) ;
            this.setAge(age) ;
        }
        public void setName(String name){
            this.name = name;    
        }
        public void setAge(int age){
            this.age = age ;
        }
        public String getName(){
            return this.name ;
        }
        public int getAge(){
            return this.age ;
        }
        public String getInfo(){
            return "姓名:" + this.getName() + ";年龄:" + this.getAge() ;
        }
    };
    class Student extends Person{                    // 定义Student类
        private String school ;        // 定义school属性
        public Student(String name,int age,String school){
            super(name,age) ;    // 明确调用父类中有两个参数的构造
            this.school = school ;
        }
        public void setSchool(String school){
            this.school = school ;
        }
        public String getSchool(){
            return this.school ;
        }
        public String getInfo(){
            return super.getInfo() + ";学校:" + this.getSchool() ;
        } 
    
    };
    public class SuperDemo01{
        public static void main(String arsg[]){
            Student stu = new Student("张三",30,"清华大学")    ;// 实例化子类对象
            System.out.println(stu.getInfo()) ;
        }
    };

    不管任何时候,子类实例化的时候,永远要先去调用父类中的构造方法,默认调用的是无参构造方法。

    1)对于this和super本身都可以调用构造方法,而且调用的时候都必须放在构造方法的首行。所以这两个方法肯定不能同时出现。

  • 相关阅读:
    [转帖]能感动天地的老人,你拿什么来感动CCTV
    SaaS, 8,9点的太阳
    ERP软件开源是中国软件行业未来之路
    觉得为时已晚的时候,恰恰是最早的时候。
    新画皮故事——ERP软件为什么要免费
    如何定制SharePoint“欢迎”菜单?
    软件产品在什么情况下一定要走精品路线
    我的blogs
    测试环境中安装sharepoint server 2010过程中出现的一些问题及解决过程
    windows server 2008 与windows server 2008 r2区别
  • 原文地址:https://www.cnblogs.com/alsf/p/5525298.html
Copyright © 2020-2023  润新知