private this static 关键字学习总结

类与对象关键字学习总结

private

this

static

private实现封装处理&构造方法(匿名对象)

private基本介绍

构造方法

构造方法的重载

匿名对象

1.private实现封装(只是封装的第一步)

当属性或方法被private关键字修饰后,该属性或方法无法在类外部调用,只能在本类中使用。

class Person{
    private String name;
    private int age;
}

public class Test{
    public static void main(String[] args){
        Person per=new Person();
        per.name="张三";
        per.age=18;
        System.out.println(per.name);
        System.out.println(per.age);
    }
}

那么如果类中属性被private修饰后,怎么初始化、获得其内容呢?

getter方法:主要用于进行属性内容的设置与修改
setter方法:主要用于属性内容的取得
class Person{
    private String name;
    private int age;

    public void setName(String n){
        name=n;
    }

    public void setAge(int a){
        if(a<0||a>200){
            System.out.println("年龄设置非法!");
        }
        else{
            age=a;
        }
    }

    public String getName(){
        return name;
    }

    public int getAge(){
        return age;
    }

    public void getPersonInfo(){
        System.out.println(name+"今年"+age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person();
        per.setName("张三");
        per.setAge(18);
        per.getPersonInfo();
    }
}

但是getter、setter的缺点是有几个属性就要调用几次进行初始化,为了减少代码冗余,就出现了构造方法,用其代替setter方法进行类属性的初始化操作。

2.构造方法

所谓构造方法就是使用关键字new实例化新对象时调用的操作方法。定义构造方法时需遵循以下原则:

(1)方法名称必须与类名称相同

(2)构造方法没有返回值类型声明

(3)每一个类中至少存在一个构造方法(若无明确定义时,系统将自行生成一个无参构造),若自定义了构造方法,系统将不再生成无参构造。

public person(){}//无参构造
public void person(){}

那么构造方法为什么没有返回值类型呢?

因为构造方法是在产生新对象时自动调用的,普通方法(不加static关键字的方法,必须由对象调用)若不调用就不会执行。故构造方法没有返回值类型。

那么以上代码就可以修改为:

class Person{
    private String name;//属性
    private int age;

    //构造方法,进行类属性的初始化(此构造方法为自定义,系统将不再生成无参构造)
    public Person(String n,int a){
        name=n;
        age=a;
    }

    public void getPersonInfo(){//普通方法
        System.out.println(name+"今年"+age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person("张三",18);
        per.getPersonInfo();//调用普通方法
    }
}

注意:

(1)若自定义了构造方法,则系统默认的无参构造将不再产生。

(2)因构造方法的调用和对象内存分配几乎是同步进行的,所以构造方法能为类中属性进行初始化操作。

那么到现在我们学到的定义一个类的构造为属性、构造方法、普通方法。

(1)属性是对象在开辟堆内存时开辟的空间;

(2)构造方法是在使用new之后调用的;

(3)普通方法是在空间开辟后、构造方法执行后可以进行多次调用。

3.构造方法的重载(参数个数不同)

接下来考虑下一个问题,既然普通方法都有方法重载(方法名称相同,参数类型或者个数不同,与返回值无关(建议返回值相同)),当然构造方法也就有,接下来让我们认识一下构造方法的重载。

class Person{
    private String name;
    private int age;

    public Person(){}//无参构造

    public Person(String n){//一个参数的有参构造
        name=n;
    }

    public Person(String n,int a){//两个参数的有参构造
        name=n;
        age=a;
    }

    public void getPersonInfo(){
        System.out.println(name+"今年"+age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person("张三");
        per.getPersonInfo();
    }
}

观察以上代码输出结果,我们可以知道调用哪个构造方法,是根据生成对象时是否传参及传参个数决定的。那么以上代码我只赋值name,并没有赋值age,为什么age输出时是数字0(int型默认值)而不是乱码呢?

原因是因为在生成对象时会执行无参构造。

public Person(){
        name=null;
        age=0;
    }
4.匿名对象
class Person{
    private String name;
    private int age;

    public Person(){}

    public Person(String n){
        name=n;
    }

    public Person(String n,int a){
        name=n;
        age=a;
    }

    public void getPersonInfo(){
        System.out.println(name+"今年"+age);
    }
}

public class Test{
    public static void main(String[] args){
        new Person("张三",18).getPersonInfo();//匿名对象
    }
}

由于匿名对象没有任何栈内存所指向,所以使用一次后就会变成垃圾空间。

this关键字

this关键字主要有三个用途:

(1)调用本类属性(此时this在构造方法、setter方法中使用)

(2)调用本类方法

(3)表示当前对象

1.调用本类属性
class Person{
    private String name;
    private int age;
    public Person(String name,int age){//属性初始化
        name=name;
        age=age;
    }
    public void getPersonInfo(){
        System.out.println(name+"今年"+age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person("张三",18);
        per.getPersonInfo();
    }
}

按照之前的学习,这段代码理应正确,可是为什么属性并没有初始化呢?

原因是我们在写代码过程中变量命名尽量都要有意义,若形参命名也为name、age时,任何语言都遵循就近原则,即name会现在构造方法中寻找是否有name变量名,此种情况就是形参恒等于形参,根本不会到达属性处,此种赋值无意义,故不会赋值。所以就有了this关键字的出现。

class Person{
    private String name;
    private int age;
    public Person(String name,int age){
        this.name=name;//this此时表示调用本类属性(打破就近原则)
        this.age=age;
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person("张三",18);
        per.getPersonInfo();
    }
}


此时this.name代表的就是本类属性,name代表的是形参,故可正常赋值。

2.调用本类方法

类中方法分为构造方法和普通方法。我们先来看调用构造方法的情况。

(1)this调用构造方法

class Person{
    private String name;
    private int age;
    public Person(){
        System.out.println("********************************");
    }
    public Person(String name){
        System.out.println("********************************");
        this.name=name;
    }
    public Person(String name,int age){
        System.out.println("********************************");
        this.name=name;
        this.age=age;
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person("张三",18);
        per.getPersonInfo();
    }
}

此段代码我们可以看到使用了构造方法的重载能正常输出,但缺点是重复代码过多(若一般情况下代码出现重复,就一定有优化的可能)此时就可以使用this关键字调用构造方法进行优化。

class Person{
    private String name;
    private int age;
    public Person(){
        System.out.println("********************************");
    }
    public Person(String name){
        this();//调用无参构造
        this.name=name;
    }
    public Person(String name,int age){
        this(name);//调用一个参数的有参构造
        this.age=age;
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person("张三",18);
        per.getPersonInfo();
    }
}

我们可以看到用this()进行构造方法调用就可以将程序优化。但这里有两个需要注意的点:

(1)this调用构造方法时必须位于本方法的首行,否则编译不通过。

//对以上代码修改
public Person(String name){
        this.name=name;
        this();
    }


(2)this调用构造方法时不能成“环”,必须是线性的。意思调用关系不能是封闭的,必须留有出口。

class Person{
    private String name;
    private int age;
    public Person(){
        this(name,age);//此时想调用两个参数的构造方法
        System.out.println("********************************");
    }
    public Person(String name){
        this();
        this.name=name;
    }
    public Person(String name,int age){
        this(name);
        this.age=age;
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person("张三",18);
        per.getPersonInfo();
    }
}

分析图:

(2)this调用普通方法

this.方法名称();
class Person{
    private String name;
    private int age;
    public Person(){
        System.out.println("********************************");
    }
    public Person(String name){
        this();
        this.name=name;
    }
    public Person(String name,int age){
        this(name);//调用本类构造方法
        this.age=age;
        this.getPersonInfo();//调用本类普通方法,与主类调用getPersonInfo方法效果一样
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age);
    }
}

public class Test{
    public static void main(String[] args){
        Person per=new Person("张三",18);
        // per.getPersonInfo();
    }
}


(3)this表示当前对象

class Person{
    private String name;
    private int age;
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public void getPersonInfo(){
        System.out.println("lala"+this);//this表示当前调用getPersonInfo方法的对象
    }
}

public class Test{
    public static void main(String[] args){
        Person per1=new Person("张三",18);
        System.out.println(per1);
        per1.getPersonInfo();
        Person per2=new Person("小花",22);
        System.out.println(per2);
        per2.getPersonInfo();
    }
}

结果显示当前是哪个对象调用普通方法、普通属性,this就代表它。

static关键字

1.static类属性(静态属性/类属性)

static属性描述共享属性,只需要在属性前加static关键字即可;如果要调用即可以类名称.属性名。

class Person{
    private String name;
    private int age;
    private String country;
    public Person(String name,int age,String country){
        this.name=name;
        this.age=age;
        this.country=country;
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age+"在"+this.country);
    }
}

public class Test{
    public static void main(String[] args){
        Person per1=new Person("张三",18,"中国");
        per1.getPersonInfo();
        Person per2=new Person("小花",22,"中国");
        per2.getPersonInfo();
    }
}


内存分析:

以上代码中两个Person对象country属性值是一样的,但如果按照之前的方法书写,那么生成多少个对象country属性就得初始化多少次,为了节省空间提升程序性能,提出了static关键字进行优化。

//在本类中定义类属性时直接赋值
class Person{
    private String name;
    private int age;
    private static String country="中国";
    public Person(String name,int age){
        this.name=name;
        this.age=age;
        //this.country=country;
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age+"在"+this.country);
    }
}

public class Test{
    public static void main(String[] args){
        Person per1=new Person("张三",18);//共享属性
        per1.getPersonInfo();
        Person per2=new Person("小花",22);
        per2.getPersonInfo();
    }
}

//从其他类给共享属性赋值
class Person{
    private String name;
    private int age;
    public static String country;//此时共享属性定义为public
    public Person(String name,int age){
        this.name=name;
        this.age=age;
        //this.country=country;
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age+"在"+this.country);
    }
}

public class Test{
    public static void main(String[] args){
        Person.country="中国";//类名.属性名
        Person per1=new Person("张三",18);
        per1.getPersonInfo();
        Person per2=new Person("小花",22);
        per2.getPersonInfo();
    }
}

static类属性就不再存储于对象中了,存在全局数据区,只需一次赋值就可为所有对象country属性赋值。

结论:

(1)访问static属性(类属性)应使用类名称.属性名。

(2)所有的非static属性(实例变量)必须在对象实例化后使用,而static属性(类属性)不受对象实例化控制

(3)static不可在方法中定义(修饰)变量,只能修饰类中属性。

(4)在定义类时99%的情况都不会考虑static属性,以非static属性为主。

**2.static类方法(类方法/静态方法) **

使用static定义的方法为类方法,与对象无关,直接通过类名称访问。

class Person{
    private String name;
    private int age;
    private static String country;
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public static void Country(String c){
        country=c;//此时不能使用this关键字调用本类属性
    }
    public void getPersonInfo(){
        System.out.println(this.name+"今年"+this.age+"在"+this.country);
    }
}

public class Test{
    public static void main(String[] args){
        Person.Country("中国");
        Person per1=new Person("张三",18);
        per1.getPersonInfo();
        Person per2=new Person("小花",22);
        per2.getPersonInfo();
    }
}

注意:

(1)static描述的类或属性在主方法产生时便会产生。

(2)所有的static方法不允许调用非static定义的属性与方法。

(因static方法与对象无关,非static定义的属性与方法必须通过对象调用,相互矛盾)

(3)所有的非static方法允许访问static方法或属性。

(没有对象都能调用static方法,必须使用对象调用的非static方法肯定也能调用)

帮助理解:假设static方法是0元,非static方法是超市价值10元的东西,那么(2)肯定不可行,(3)就一定可行。

使用static定义方法的目的只有一个:某些方法不希望受到对象的限制,即可以在没有实例化对象的时候执行(广泛存在于工具类中)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值