zoukankan      html  css  js  c++  java
  • java--面对对象之this关键字和super关键字

    this

    一、this调用构造方法

    构造方法之间的调用,可以通过this关键字来完成。

    构造方法调用格式:

    1 this(参数列表);

    构造方法的调用:

    二、this的原理图解

        了解了构造方法之间是可以相互调用,那为什么他们之间通过this就可以调用呢?通过上面的学习,简单知道使用this可以实现构造方法之间的调用,但是为什么就会知道this调用哪一个构造方法呢?接下来需要图解完成。

     图列说明:

    1、先执行main方法,main方法压栈,执行其中的new Person(“张三”,23);

    2、堆内存中开辟空间,并为其分配内存地址0x33,,紧接着成员变量默认初始化(name=null  age = 0);

    3、拥有两个参数的构造方法(PersonString nm , int a))压栈,在这个构造方法中有一个隐式的this,因为构造方法是给对象初始化的,那个对象调用到这个构造方法,this就指向堆中的那个对象。

    4、由于PersonString nm , int a)构造方法中使用了this(nm);构造方法Person(String nm)就会压栈,并将“张三”传递给nm。在PersonString nm , int a)构造方法中同样也有隐式的thisthis的值同样也为0x33,这时会执行其中name = nm,即把“张三”赋值给成员的name。当赋值结束后PersonString nm , int a)构造方法弹栈。

    5、程序继续执行构造方法(PersonString nm , int a)中的age = a;这时会将23赋值给成员属性age。赋值结束构造方法(PersonString nm , int a)弹栈。

    6、当构造方法(PersonString nm , int a)弹栈结束后,Person对象在内存中创建完成,并将0x33赋值给main方法中的p引用变量。

    注意:

           this到底代表什么呢?this代表的是对象,具体代表哪个对象呢?哪个对象调用了this所在的方法,this就代表哪个对象。

    调用其他构造方法的语句必须定义在构造方法的第一行,原因是初始化动作要最先执行。 

    三、成员变量和局部变量同名问题

            当在方法中出现了局部变量和成员变量同名的时候,那么在方法中怎么区别局部变量成员变量呢?可以在成员变量名前面加上this.来区别成员变量和局部变量。

    public class Person {
        private int age;
        private String name;
    
        // 给姓名和年龄初始化的构造方法
        Person(String name, int age) {
            // 当需要访问成员变量是,只需要在成员变量前面加上this.即可
            this.name = name;
            this.age = age;
        }
    
        public void speak() {
            System.out.println("name=" + this.name + ",age=" + this.age);
        }
    }
    class PersonDemo {
        public static void main(String[] args) {
            Person p = new Person("张三", 23);
            p.speak();
        }
    }

    四、this的应用

    学习完了构造方法、this的用法之后,现在做个小小的练习。

    需求:在Person类中定义功能,判断两个人是否是同龄人

     1 class Person {
     2     private int age;
     3     private String name;
     4 
     5     // 给姓名和年龄初始化的构造方法
     6     Person(String name, int age) {
     7         // 当需要访问成员变量是,只需要在成员变量前面加上this.即可
     8         this.name = name;
     9         this.age = age;
    10     }
    11 
    12     public void speak() {
    13         System.out.println("name=" + this.name + ",age=" + this.age);
    14     }
    15 
    16     // 判断是否为同龄人
    17     public boolean equalsAge(Person p) {
    18         // 使用当前调用该equalsAge方法对象的age和传递进来p的age进行比较
    19         // 由于无法确定具体是哪一个对象调用equalsAge方法,这里就可以使用this来代替
    20         /*
    21          * if(this.age == p.age) { return true; } return false;
    22          */
    23         return this.age = p.age;
    24     }
    25 }

    super

    一、子父类中构造方法的调用

    在创建子类对象时,父类的构造方法会先执行,因为子类中所有构造方法的第一行有默认的隐式super();语句。

    格式:

    1 调用本类中的构造方法
    2 this(实参列表);
    3 调用父类中的空参数构造方法
    4 super();
    5 调用父类中的有参数构造方法
    6     super(实参列表);

    为什么子类对象创建都要访问父类中的构造方法?因为子类继承了父类的内容,所以创建对象时,必须要先看父类是如何对其内容进行初始化的,看如下程序:

     1 //父类
     2 public class Person {
     3     int a=1;
     4     public Person(){
     5         
     6     }
     7     public Person(String name){
     8         a=5;
     9         System.out.println("父类构造方法");
    10     }
    11 }
    12 //子类
    13 public class Test {
    14 
    15     public static void main(String[] args) {
    16         Student stu=new Student("name");
    17 
    18     }
    19 }
    20 //测试类
    21 public class Test {
    22 
    23     public static void main(String[] args) {
    24         Student stu=new Student("name");
    25 
    26     }
    27 }

    运行结果为:

    父类构造方法
    5

    总结:通过结果发现,子类构造方法执行时中,调用了父类构造方法,这说明,子类构造方法中有一句super()

    那么,子类中的构造方法为什么会有一句隐式的super()呢?

    原因:子类会继承父类中的内容,所以子类在初始化时,必须先到父类中去执行父类的初始化动作。这样,才可以使用父类中的内容。

    当父类中没有空参数构造方法时,子类的构造方法必须有显示的super语句,指定要访问的父类有参数构造方法。

    二 、子类对象创建过程的细节

    如果子类的构造方法第一行写了this调用了本类其他构造方法,那么super调用父类的语句还有吗?

    这时是没有的,因为this()或者super(),只能定义在构造方法的第一行,因为初始化动作要先执行。

    父类构造方法中是否有隐式的super呢?

    也是有的。记住:只要是构造方法默认第一行都是super();

    父类的父类是谁呢?super调用的到底是谁的构造方法呢?

    Java体系在设计,定义了一个所有对象的父类Object

     注意:

        1、类中的构造方法默认第一行都有隐式的super()语句,在访问父类中的空参数构造方法。所以父类的构造方法既可以给自己的对象初始化,也可以给自己的子类对象初始化。

        2、如果默认的隐式super()语句在父类中没有对应的构造方法,那么必须在构造方法中通过this或者super的形式明确要调用的构造方法。

    三、super应用

        描述学生和工人这两个类,将他们的共性nameage抽取出来存放在父类中,并提供相应的getset方法,同时需要在创建学生和工人对象就必须明确姓名和年龄。

     1 //定义Person类,将Student和Worker共性抽取出来
     2 class Person {
     3     private String name;
     4     private int age;
     5     public Person(String name, int age) {
     6         // super();
     7         this.name = name;
     8         this.age = age;
     9     }
    10     public String getName() {
    11         return name;
    12     }
    13     public void setName(String name) {
    14         this.name = name;
    15     }
    16     public int getAge() {
    17         return age;
    18     }
    19     public void setAge(int age) {
    20         this.age = age;
    21     }
    22 }
    23 class Student extends Person {
    24     // Student类的构造方法
    25     Student(String name, int age) {
    26         // 使用super关键字调用父类构造方法,进行相应的初始化动作
    27         super(name, age);
    28     }
    29     public void study() {// Studnet中特有的方法
    30         System.out.println(this.getName() + "同学在学习");
    31     }
    32 }
    33 class Worker extends Person {
    34     Worker(String name, int age) {
    35         // 使用super关键字调用父类构造方法,进行相应的初始化动作
    36         super(name, age);
    37     }
    38     public void work() {// Worker 中特有的方法
    39         System.out.println(this.getName() + "工人在工作");
    40     }
    41 }
    42 public class Test {
    43     public static void main(String[] args) {
    44         Student stu = new Student("小明",23);
    45 stu.study();
    46         
    47 Worker w = new Worker("小李",45);
    48 w.work();
    49     }
    50 }
  • 相关阅读:
    asp.net core过滤器记录响应对象
    ef core实现无感知软删除
    Egret资源跨域问题
    ASP.Net Core中使用jquery-ajax-unobtrusive替换Ajax.BeginForm
    把.Net开发环境迁移到Linux上去
    Mysql8.0升级后,Navicat连接报错caching_sha2_password 问题
    改MySQL的编码方式,解决jdbc MySQL中文乱码问题
    怡红公子专属网址导航
    html以前没有学到的标签
    有哪些质量上乘的程序员必关注的网站或论坛
  • 原文地址:https://www.cnblogs.com/-dashu/p/9366983.html
Copyright © 2011-2022 走看看