java类和对象(下)

一、private实现封装

        封装(encapsulation,有时也称数据隐藏)是与对象有关的一个重要概念。对象中的数据称为实例域(instance field),操纵数据的过程称为方法。所谓封装,也就是把客观事物封装成抽象的类,并且类可以把⾃⼰的数据和⽅法只让可信的类或者对象操作,对不可信的进⾏信息隐藏。简⽽⾔之就是,内部操作对外部⽽⾔不可⻅(保护性)。

首先看一个无封装范例:

class Employee {
     String name;
     int age;
     double salary;

    public void get() {
        System.out.println("名字" + name + "年龄" + age + "薪资" + salary);
    }
}
public class Demo3{
    public static void main(String[]args){
        Employee person1=new Employee();
        person1.name="king";
        person1.age=-28;
        person1.salary=100000;
        person1.get();

    }
}

运行结果:

结果我们看见人的年龄是-28,这是由于对象可以在类的外部直接访问属性。为了避免此类问题,让内部操作对外不可见(对象不能直接操作属性),可以使用private进行封装。

     private String name;
     private int age;
     private double salary;

 此时使用private对属性进行了封装,要访问私有私有属性,那么按照要求,需要定义属性相应的1、setter 2、 getter方法

1、setter方法:主要用于属性内容的设置与修改(注意有参数)

 public void setName(String name)

2、getter方法:主要用于属性内容的取得(没有参数)

 public String getName()

为封装属性设置getter、setter方法

class Employee {
     private String name;
     private int age;
     private double salary;

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }

    public void setAge(int age) { this.age = age; }

    public double getSalary() { return salary; }

    public void setSalary(double salary) { this.salary = salary; }

    public void get() {
        System.out.println("名字" + name + "年龄" + age + "薪资" + salary);
    }
}
public class Demo3{
    public static void main(String[]args){
        Employee person1=new Employee();
        person1.setName("king");
        person1.setAge(-28);
        person1.setSalary(100000);
        person1.get();

    }
}

结果如下:

       此时我们发现private封装最大的特点就是只允许本类访问而不允许外部类访问。然而此时人的年龄是负数,需要加入检查逻辑错误的代码,可以在setter中增加验证,如果值为正则赋值,为负则默认0:

 public void setAge(int age) {
        if(age>0){
        this.age=age;
        }
    }

结果如下:

对于数据验证,在java标准开发中应该由辅助代码完成,在实际开发中,setter一般只是简单的设置属性内容,getter只是简单的取得属性内容。

类的设计原则:编写类时,类中的所有属性必须用private封装。

                         属性若要被外部访问,则必须定义getter、setter方法。

二、构造方法

  先来看对象的产生格式:

①类名称 ②对象名称 = ③new ④类名称();

根据以上定义做以下分析:

①任何对象都有对应的类,类是对象的蓝图,即规定了对象的类型(对象可以使用哪些属性和方法是由类定义的)。

②要使用对象,需要一个名称,这是唯一的一个标记,引用一块堆内存。

③开辟新的堆内存空间。

④调用了名称和类名称相同的方法,这就是构造方法。

结论:所谓的构造方法就是关键字new实例化新对象时来调用的操作方法。

对于构造方法的定义·,也需要遵循以下原则:

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

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

(3)每一个类中必须至少定义一个构造方法(没有明确定义,则系统自动生成一个无参构造)

范例:一个与类名称相同,无参、无返回值的构造方法

 public Employee(){

    }

对上面提到的(3)可以看以下范例:


class Employee {
     private String name;
     private int age;
     private double salary;
     public Employee(){
         System.out.println("这是一个无参的构造方法");
    }
}
public class Demo3{
    public static void main(String[]args){
        Employee person1=null;
    }
}

结果:

并没有打印出东西。接下来加入实例化代码

public class Demo3{
    public static void main(String[]args){
        Employee person1=null;//声明对象
        person1 = new Employee();//实例化对象

    }
}

 结果:

结论:关键字new分配内存空间实例化对象时构造方法才被调用

思考:构造方法没有返回值,为什么没有void声明?

==>1、属性是在对象开辟堆内存时开辟的空间

      2、构造方法是在new后调用的(只调用一次)

      3、普通方法是在空间开辟了,构造方法执行之后多次调用的

public void Emplayee() {}  //命名不标准的普通方法
public Emplayee() {}      //无参构造方法

==>因此编译器是根据程序结构来区分普通方法和构造方法的,所以在构造方法前,没有返回值声明。

建议:在定义时:①定义属性==>②定义构造方法==>③定义普通方法

在实际开发中,构造方法的作用是在类对象实例化的时候设置属性的初始化内容: 

class Employee {
     private String name;
     private int age;
     private double salary;
     public Employee(String name,int age,double salary){
         this.name=name;
         this.age=age;
         this.salary=salary;
    }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }

    public void setAge(int age) { this.age=age; }

    public double getSalary() { return salary; }

    public void setSalary(double salary) { this.salary = salary; }


    public void get() {
        System.out.println("名字" + name + "年龄" + age + "薪资" + salary);
    }
}
public class Demo3{
    public static void main(String[]args){
        Employee person1=null;//声明对象
        person1 = new Employee("king",28,100000);//实例化对象
        person1.get();

    }
}

结果:

构造方法重载 

构造方法也属于方法,所以构造方法也可以重载

重载:函数名相同,参数列表不同,返回值不做要求

范例:

class Employee {
     private String name;
     private int age;
     private double salary;

     public Employee() {
         System.out.println("这是一个无参的构造方法");
     }

     public Employee(String name){
         this.name=name;
         System.out.println("这是有一个参数的构造方法");
     }

     public Employee(String name,int age,double salary){
         this.name=name;
         this.age=age;
         this.salary=salary;
         System.out.println("这是有三个参数的构造方法");
    }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }

    public void setAge(int age) { this.age=age; }

    public double getSalary() { return salary; }

    public void setSalary(double salary) { this.salary = salary; }


    public void get() {
        System.out.println("名字" + name + "年龄" + age + "薪资" + salary);
    }
}
public class Demo3{
    public static void main(String[]args){
        Employee person1=new Employee();
        person1.get();

        Employee person2=new Employee("king");
        person2.get();

        Employee person3=new Employee("king",28,10000);
        person3.get();
    }
}

结果:

  

 构造方法重载时建议:按照参数个数升序或降序

 如果类中的属性直接设置默认值

     private String name="queen";
     private int age=18;
     private double salary=20000;

结果:

结论: (1)在类中直接设置属性默认值(2)这个默认值是在构造方法执行后设置的(3)属性内容为对应数据类型默认值时,属性才会设置类中定义的默认值;但是在构造方法没有执行之前,属性内容都是其对应的数据类型的默认值

三、匿名对象

        new Employee("这是个托",18,2000).get();

没有名称的对象称为匿名对象,对象的名称(保存的堆内存的地址),在上篇提过其内存关系,如下图:

匿名对象没有对象名称,也就是没有栈内存指向堆内存,所以匿名对象使用一次后就称为垃圾空间。

 范例:

class Employee {
     private String name;
     private int age;
     private double salary;
public Employee(String name,int age,double salary){
         this.name=name;
         this.age=age;
         this.salary=salary;
         System.out.println("这是有三个参数的构造方法");
    }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }

    public void setAge(int age) { this.age=age; }

    public double getSalary() { return salary; }

    public void setSalary(double salary) { this.salary = salary; }


    public void get() {
        System.out.println("名字:" + name + "年龄:" + age + "薪资:" + salary);
    }
}
public class Demo3{
    public static void main(String[]args){
 new Employee("这是个托",18,2000).get();
    }
}

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值