【问题标题】:Difference between "this" and"super" keywords in JavaJava中“this”和“super”关键字的区别
【发布时间】:2011-04-30 17:11:02
【问题描述】:

关键字this和super有什么区别?

两者都用于访问类的构造函数,对吧?谁能解释一下?

【问题讨论】:

    标签: java keyword


    【解决方案1】:

    让我们考虑一下这种情况

    class Animal {
      void eat() {
        System.out.println("animal : eat");
      }
    }
    
    class Dog extends Animal {
      void eat() {
        System.out.println("dog : eat");
      }
      void anotherEat() {
        super.eat();
      }
    }
    
    public class Test {
      public static void main(String[] args) {
        Animal a = new Animal();
        a.eat();
        Dog d = new Dog();
        d.eat();
        d.anotherEat();
      }
    }
    

    输出将是

    animal : eat
    dog : eat
    animal : eat
    

    第三行打印“animal:eat”,因为我们调用的是super.eat()。如果我们调用this.eat(),它会打印为“dog:eat”。

    【讨论】:

    • 我不觉得这个答案令人困惑,尽管您可以将输出的最后一行加粗或添加尾随注释以强调使用了基类。
    【解决方案2】:

    super用于访问基类的方法,this用于访问当前类的方法。

    扩展概念,如果你写super(),它指的是基类的构造函数,如果你写this(),它指的是你正在编写这段代码的那个类的构造函数。

    【讨论】:

      【解决方案3】:

      this 是对类型为当前类的对象的引用,super 是对类型为父类的对象的引用。

      在构造函数中,this() 调用当前类中定义的构造函数。 super() 调用父类中定义的构造函数。构造函数可以在任何父类中定义,但它将引用最接近当前类的重写。以这种方式调用其他构造函数只能作为构造函数的第一行。

      调用方法的工作方式相同。调用this.method() 会调用当前类中定义的方法,而super.method() 将调用父类中定义的相同方法。

      【讨论】:

        【解决方案4】:

        根据您的问题,我认为您实际上是在询问 this 和 super 在构造函数链接中的使用;例如

        public class A extends B {
            public A(...) {
                this(...);
                ...
            }
        }
        

        对

        public class A extends B {
            public A(...) {
                super(...);
                ...
            }
        }
        

        区别很简单:

        • this 表单链接到当前类中的构造函数;即在A 类中。

        • super 表单链接到直接超类中的构造函数;即在B 类中。

        【讨论】:

          【解决方案5】:

          this 引用 current 类。
          super 指的是当前类的父类(称为super 关键字)。

          通过this,它允许您访问当前类的方法/属性(包括它自己的私有方法/属性)。

          super 允许您访问父(基)类的公共/受保护方法/属性。您看不到父级的私有方法/属性。

          【讨论】:

          • 如果您将每次出现的“类”都更改为“对象”,那么这个答案是正确的。例如,不可能从类中的静态方法调用“this”。
          • @Dave,真的......我基本上继续了 super 调用基类的事实(因为它是基类的派生类)。我应该说基础对象吗?如果是这样,类/对象之间有什么区别?
          • @TEG,我知道这有点玩弄文字,很多人使用类和对象作为同义词。类实际上是定义,可能有静态方法、常量,甚至可能没有被实例化的可能性(抽象类)。对象只能在运行时存在,并且必须使用“new”关键字创建。
          • @Dave,是的,但是如果您查看文献,您会看到诸如 base 和 derived 类之类的词,而不是 based 和 derived 对象。也许新文学区分了差异。
          • @TEG,我同意在类图(或技术分析)的上下文中使用“基础”和“派生”类分别作为超类和子类的更非正式命名。
          【解决方案6】:

          super() & this()

          • super() - 调用父类构造函数。
          • this() - 调用相同的类构造函数。

          注意:

          • 我们只能在构造函数中使用 super() 和 this() 不能在其他任何地方使用,任何 尝试这样做会导致编译时错误。

          • 我们必须保留 super() 或 this() 作为 构造函数,但不能同时进行。

          super & this 关键字

          • super - 调用父类成员(变量和方法)。
          • this - 调用相同的类成员(变量和方法)。

          注意:我们可以在类中的任何地方使用它们,除了静态区域(静态块或方法),任何 尝试这样做会导致编译时错误。

          【讨论】:

            【解决方案7】:

            this 用于访问当前对象的方法和字段。因此,例如,它在静态方法中没有任何意义。

            super 允许访问超类中的非私有方法和字段,并且只能从类的构造函数中访问构造函数。

            【讨论】:

              【解决方案8】:

              在编写代码时,您通常不想重复自己。如果您有一个可以用各种数量的参数构造的类,避免重复自己的常见解决方案是简单地调用另一个构造函数,并在缺少的参数中使用默认值。对此只有一个烦人的限制——它必须是声明的构造函数的第一行。示例:

              MyClass()
              {
                 this(default1, default2);
              }
              
              MyClass(arg1, arg2)
              {
                 validate arguments, etc...
                 note that your validation logic is only written once now
              }
              

              至于super() 构造函数,与super.method() 访问不同,它必须是构造函数的第一行。之后,它非常类似于this() 构造函数,DRY(不要重复自己),如果您扩展的类有一个构造函数可以执行您想要的某些操作,那么使用它然后继续构造您的对象,例如:

              YourClass extends MyClass
              {
                 YourClass(arg1, arg2, arg3)
                 {
                    super(arg1, arg2) // calls MyClass(arg1, arg2)
                    validate and process arg3...
                 }
              }
              

              附加信息:

              即使你没有看到它,默认的无参数构造函数总是首先调用super()。示例:

              MyClass()
              {
              }
              

              等价于

              MyClass()
              {
                 super();
              }
              

              我看到很多人提到在方法和变量上使用 this 和 super 关键字 - 都很好。请记住,构造函数对其使用有独特的限制,最值得注意的是它们必须是声明的构造函数的第一条指令,并且您只能使用一个。

              【讨论】:

                【解决方案9】:

                this关键字用于调用同一类中的构造函数(其他重载的构造函数)

                语法:this(参数列表); //兼容args list在同一个类的其他构造函数

                super 关键字用于调用超类中的构造函数。

                语法: super(参数列表); //兼容超类构造函数中的args list。

                例如:

                public class Rect {
                int x1, y1, x2, y2;
                
                public Rect(int x1, int y1, int x2, int y2) // 1st constructor 
                { ....//code to build a rectangle }
                }
                
                public Rect () {   // 2nd constructor
                this (0,0,width,height) // call 1st constructor (because it has **4 int args**), this is another way to build a rectangle 
                }
                
                
                public class DrawableRect extends Rect {
                
                public DrawableRect (int a1, int b1, int a2, int b2) {
                super (a1,b1,a2,b2) // call super class constructor (Rect class) 
                }
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-10-29
                  • 1970-01-01
                  • 2023-03-10
                  • 1970-01-01
                  • 2011-05-20
                  • 1970-01-01
                  • 2014-04-10
                  相关资源
                  最近更新 更多