Java中this和super的用法总结

this

this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。

this的用法在java中大体可以分为3种:

1.普通的直接引用

这种就不用讲了,this相当于是指向当前对象本身。

2.形参与成员名字重名,用this来区分:

class Person {
    private int age = 10;
    public Person(){
    System.out.println("初始化年龄:"+age);
}
    public int GetAge(int age){
        this.age = age;
        return this.age;
    }
}
 
public class test1 {
    public static void main(String[] args) {
        Person Harry = new Person();
        System.out.println("Harry's age is "+Harry.GetAge(12));
    }
}       
运行结果:

初始化年龄:10
Harry's age is 12

可以看到,这里age是GetAge成员方法的形参,this.age是Person类的成员变量。

3.引用构造函数

这个和super放在一起讲,见下面。

super

super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。

super也有三种用法:

1.普通的直接引用

与this类似,super相当于是指向当前对象的父类,这样就可以用super.xxx来引用父类的成员。

2.子类中的成员变量或方法与父类中的成员变量或方法同名

class Country {
    String name;
    void value() {
       name = "China";
    }
}
  
class City extends Country {
    String name;
    void value() {
    name = "Shanghai";
    super.value();      //调用父类的方法
    System.out.println(name);
    System.out.println(super.name);
    }
  
    public static void main(String[] args) {
       City c=new City();
       c.value();
       }
}
运行结果:

Shanghai
China

可以看到,这里既调用了父类的方法,也调用了父类的变量。若不调用父类方法value(),只调用父类变量name的话,则父类name值为默认值null。

3.引用构造函数super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。

class Person { 
    public static void prt(String s) { 
       System.out.println(s); 
    } 
   
    Person() { 
       prt("父类·无参数构造方法: "+"A Person."); 
    }//构造方法(1) 
    
    Person(String name) { 
       prt("父类·含一个参数的构造方法: "+"A person's name is " + name); 
    }//构造方法(2) 
} 
    
public class Chinese extends Person { 
    Chinese() { 
       super(); // 调用父类构造方法(1) 
       prt("子类·调用父类”无参数构造方法“: "+"A chinese coder."); 
    } 
    
    Chinese(String name) { 
       super(name);// 调用父类具有相同形参的构造方法(2) 
       prt("子类·调用父类”含一个参数的构造方法“: "+"his name is " + name); 
    } 
    
    Chinese(String name, int age) { 
       this(name);// 调用具有相同形参的构造方法(3) 
       prt("子类:调用子类具有相同形参的构造方法:his age is " + age); 
    } 
    
    public static void main(String[] args) { 
       Chinese cn = new Chinese(); 
       cn = new Chinese("codersai"); 
       cn = new Chinese("codersai", 18); 
    } 
}
运行结果:

父类·无参数构造方法: A Person.
子类·调用父类”无参数构造方法“: A chinese coder.
父类·含一个参数的构造方法: A person's name is codersai
子类·调用父类”含一个参数的构造方法“: his name is codersai
父类·含一个参数的构造方法: A person's name is codersai
子类·调用父类”含一个参数的构造方法“: his name is codersai
子类:调用子类具有相同形参的构造方法:his age is 18

从本例可以看到,可以用super和this分别调用父类的构造方法和本类中其他形式的构造方法。

例子中Chinese类第三种构造方法调用的是本类中第二种构造方法,而第二种构造方法是调用父类的,因此也要先调用父类的构造方法,再调用本类中第二种,最后是重写第三种构造方法。

super和this的异同:

  • super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 
  • this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
  • super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名    super.成员函数据名(实参)
  • this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
  • 调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
  • super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。
  • super()和this()均需放在构造方法内第一行。
  • 尽管可以用this调用一个构造器,但却不能调用两个。
  • this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
  • this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
  • 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

Java中private的使用

Java中也有为了数据的封装性而声明的private类型。这篇就使用一下,大致的用法和C++类似。

    Java中引入private的类型,目的是为了防止类中的数据成员,在类的定义之外被修改。也就说,private类型的数据成员只能在定义的时候修改,其余任何地方都不可以,该类的对象也不可以。而且,private类型的数据可以作为构造函数的输入。不过,我们也可以在类中定义读取和修改private类型数据的public函数。

this.age=age;等号左右两边各代表什么?

this是java中的一个指向当前对象的引用,也就是说,你实例化一个对象的时候,可以在对象内部使用this引用对象本身。因此this.age=age;的意思是说,将当前对象的age属性,赋值为age,后面的age是从外部传入的一个参数。

java this 三种用法

 1.区分成员变量和局部变量

    public class ThisDemo {
            public static void main(String[] args) {
                Student s=new Student(“小明明”,20);
                System.out.println(s);
            }
        }
        class Student{
            String name;
            int age;
            public Student(String name, int age) {
                //注:没有加this
                name = name;
                age = age;
            }
            @Override
            public String toString() {
                return “Student [ name=” + name + “, age=” + age +”]”;
            }
        }

    打印结果:Student [ name=null, age=0]
    赋值没有成功,说明:name(局部变量)=name(局部变量);
    而不是name(成员变量)=name(局部变量);
     
    public Student(String name, int age) {
            //注:可以使用this进行区分成员变量和局部变量
            this.name = name;
            this.age = age;
    }

    打印结果:Student [ name=小明明, age=20]
    这样子就可以赋值成功啦

2.代表当前对象

    public static void main(String[] args) {
                Student s=new Student(“小明明”,20);
                System.out.println(s);
        }
        //为什么加入this后就可以区分呢?
        因为this当前代表的是s实例(对象)相当于
        s.name=”小明明”;
        s.age=”20″;
        //再可以理解如下
        this.name=实例(对象).name=”小明明”;

3.构造器与构造器之间的调用

为Student再添加两个构造器,修改后如下:

        class Student{
            String name;
            int age;
            int id;
     
            public Student(int id,String name, int age) {
                this.id = id;
                this.name = name;
                this.age = age;
            }
     
     
            public Student(String name, int age) {
                this.name = name;
                this.age = age;
            }
     
            public Student(String name) {
                this.name = name;
            }
     
            @Override
            public String toString() {
                return “Student [ id=” + id + “, name=” + name + “, age=” + age +”]”;
            }
        }

    //构造器用法–>this();跟函数一样()中可以写参数
    构造器调用一般是这样子用的.不同的构造器中存在相同代码.为了复用性。可以在参数少的构造器中调用参数多的构造器,如下:

    class Student{
            String name;
            int age;
            int id;
            public Student(String name, int age, int id) {
                this.name = name;
                this.age = age;
                this.id = id;
                System.out.println(“构造器3已调用”);
            }
            public Student(String name, int age) {
                this(name,age,0);
                System.out.println(“构造器2已调用”);
            }
     
            public Student(String name) {
                this(name,0);//参数不足,就使用参数默认值补全
                System.out.println(“构造器1已调用”);
            }
            @Override
            public String toString() {
                return “Student [ id=” + id + “, name=” + name + “, age=” + age +”]”;
            }
        }

    测试结果1:
        public static void main(String[] args) {
            Student s=new Student(“小明明”);
            System.out.println(s);
        }   
     
        构造器3已调用
        构造器2已调用
        构造器1已调用
        Student [ id=0, name=小明明, age=0]
     
    测试结果2:
        public static void main(String[] args) {
            Student s=new Student(“小明明”,20);
            System.out.println(s);
        }
        构造器3已调用
        构造器2已调用
        Student [ id=0, name=小明明, age=20]
     
    总结:这样子可以在参数最多的构造器中编写代表。其他构造器负责调用参数最多的那个构造器就好了

Java为什么会引入set/get方法??
        显然回答这个问题,我们需要了解封装

        封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装的最基本单位,面向对象的封装比传统语言的封装更为清晰、更为有力。面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。

        简单的讲封装的含义即是:类得设计者把类设计成为一个黑匣子,使用者只能看到类中定义的公共方法,而看不见方法的实现细节,当然了也不能直接对类中的数据进行操作。

       为实现封装性,常将类的成员变量声明为private,再通过public的方法来对这个变量进行访问。

那么当我们想要操作这些变量时该怎么怎么办呢??
       操作封闭在类内部的变量的方法

      <1>通过public方式的构造函数——-对象已实例化就对该变量赋值。

      <2>通过set、get方法

      set是设置,而get是获取,这两个方法是对数据进行设置和获取用的。而且,在类中使用set和get方法时,都是在set和get后面跟上一些特定的词来形成特定意思的方法名,比如set xxx()和get xxx(),表示设置xxx和获取xxx。

我们先来看看set和get这两个词的表面意思,set是设置的意思,而get是获取的意思,顾名思义,这两个方法是对数据进行设置和获取用的。而且,在类中使用set和get方法时,都是在set和get后面跟上一些特定的词来形成特定意思的方法名,比如setage()和getage(),表示设置年龄和获取年龄。
然后我们来了解一下JAVA面向对象编程中的封闭性和安全性。封闭性即对类中的域变量进行封闭操作,即用private来修饰他们,如此一来其他类则不能对该变量访问。这样我们就将这些变量封闭在了类内部,这样就提高了数据的安全性,当我们想要操作这些域变量怎么办呢?我们可以通过两种方法,第一中即通过public方式的构造器(或称构造函数),对象一实例化就对该变量赋值。第二种就是通过上面提到的set和get方法,这里我举一个特定的例子,我定义一个Person类,该类中有name、age这两个私有域变量,然后我定义setname()、getname()、setage()、getage()这四个方法,通过这四个方法来实现对name和age的操作。这样一来,我不用直接对Person类中的域变量操作,而是通过set和get方法间接地操作这些变量,这样就能提高域变量的安全性,同时又保证了域变量的封装型。

最后说说set和get方法的使用场景,一般来说set和get方法都是对私有域变量进行操作的,所以大多数都是使用在包含特定属性的类实体中。
现在你明白set和get方法了吧,其实这两个方法只是类中的setxxx和getxxx方法的总称。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇