java 深入理解自定义类 、构造器 、显式参数与隐式参数

来源:互联网 发布:宝宝网络语言什么意思 编辑:程序博客网 时间:2024/06/01 08:06
package 第3章;import java.time.*;public class 第3章a{    public static void main(String[] args)    {       Employee[] man=new Employee[2];       man[0]=new Employee("hello",200000,2003,2,8);       man[1]=new Employee("well",300000,2005,1,29);       for(Employee a:man)            System.out.println("name is "+a.getName()+", salary is "+a.getSalary()+", hireTime is "+a.getHireTime());       for(Employee b:man)       {           b.increaseSalary(5);       }       for(Employee c:man)            System.out.println(c.getSalary());    }}class Employee{    private double salary;    private String name;    private LocalDate hireTime;    public Employee(String n,double s,int year,int month,int day)    {        name=n;        salary=s;        hireTime=LocalDate.of(year, month, day);      }    public String getName()    {        return name;    }    public double getSalary()    {        return salary;    }    public LocalDate getHireTime()    {        return hireTime;    }    public void increaseSalary(double number)    {        double increase=salary*number/100;        salary+=increase;    }}

下面对Employee类进行剖析。首先从这个类的方法开始。通过查看源代码会发现,这个类包含一个构造器和4个方法。
public Employee(String n,double s,int year,int month,int day);
public String getName();
public double getSalary()
public LocalDate getHireTime();
public void increaseSalary(double number);
这个类的所有方法都被标记为public。关键字public意味着任何类的任何方法都可以调用这些方法(共有4种访问级别)
接下来,需要注意在Employee类的实例中有三个实例域用来存放将要操作的数据:

    private double salary;    private String name;    private LocalDate hireTime;

关键字private确保只有Employee类自身的方法能够访问这些实例域,而其他类的方法不能够读写这些域。
类=域+构造器+方法;
可以用public标记实例域,但这是一种极为不提倡的方法。public 数据与允许程序中的任何方法对其进行读取和修改。这就完全破坏了封装。任何类的任何方法都可以修改public域。从我们的经验看来,某些代码将使用这种存取权限,而这并不是我们希望的。因此,强烈建议将实例域标记为private
最后,请注意,有两个实例域本身就是对象:name域是String对象,hireDay域是LocalDate类对象。
?salary是不是double的实力对象?
这种情形十分常见:类通常包括属于某个类类型的实例域。 ?
从构造器开始
构造器:

public Employee(String n,double s,int year,int month,int day)    {        name=n;        salary=s;        hireTime=LocalDate.of(year, month, day);      }

可以看到,构造器与类同名。在构造Employee类的对象时,构造器会运行,以便将实例域初始化为所希望的状态。
例如:当使用下面这条代码创建Employee类实例时:

new Employee("James Bond",1000,1950,1,1);

将会把实例域设置为:

name="James Bond";salary=1000;hireDay=LocalDate.of(1950,1,1);

构造器与其他方法有一个重要的不同。构造器总是伴随着new操作符的执行被调用,而不能对一个已经存在的对象调用构造器来达到重新设置实例域的目的。例如:

james.Employee("James Bond",1000,1950,1,1)  //编译错误

本章稍后还有更详细的介绍有关构造器的内容,现在需要记住:
1、构造器与类同名;
2、每个类有一个以上的构造器;
3、构造器可以有0个,1个,或者多个参数;
4、构造器没有返回值;
5、构造器总是伴随着new操作一起调用;

public Employee(String n,double s,int year,int month,int day)    {        name=n;        salary=s;        hireTime=LocalDate.of(year, month, day);      }
Employee a=new Employee("James Bond",1000,1950,1,1);

所有的Java对象都是在堆中构造的,构造器总是伴随着new操作符一起使用。
注意,不要在构造器中定义域与实例域重名的局部变量。例如,下面的构造器将无法设置salary

//实例域    private double salary;    private String name;    private LocalDate hireTime;
public Emplyee(String n , double s){           String name=n ;        double salary=s ;}

这个构造器声明了局部变量name和salary。这些变量只能在构造器内部访问。
这些局部变量屏蔽了同名的实例域。

隐式参数与显式参数
方法用于操作对象以及存取它们的实例域。例如:方法raiseSalary:

public void raiseSalary(double byPercent){        double raise=salary*byPercent/100;        salary+=raise;}public double getSalary()    {        return salary;    }

将调用这个方法的对象的salary实例域设置为新值

  private double salary;  for(Employee b:man)       {           b.increaseSalary(5);       }       for(Employee c:man)            System.out.println(c.getSalary());

下面的这个调用:
number007.raiseSalary(5);
它的结果将number007.salary的值增加5%。具体的说,这个调用将执行下列命令:
double raise=number007.salary*byPercent/100;
number007. salary+=raise;
raiseSalary方法有两个参数。第一个参数称为隐式(implicit)参数,时出现在方法名前的Employee类对象。第二个参数为与方法后面括号中的数值,这是一个显式(explicit)参数。(有人把隐式参数称为方法调用的目标或者接受者)。
可以看到,显示参数是明显的列在方法声明中的,例如double byPercent。隐式参数没有出现在方法声明中。
在每一个方法中,关键字this表示隐式参数。如果需要的话,可以用下列方式编写raiseSalary方法:

public void raiseSalary(double byPercent){        double raise=this.salary*byPercent/100;        this.salary+=raise;}//对比public void increaseSalary(double number)    {        double increase=salary*number/100;        salary+=increase;    }

类的方法的调用者都有一个隐式的此类的实例作为调用对象:

Employee[] man=new Employee[2];man[0]=new Employee("hello",200000,2003,2,8);a.getName()a.getSalary()a.getHireTime()b.increaseSalary(5);

有些程序员偏爱这样的风格,因为这样可以将实例域与局部变量声明明显的区分开。

 increase=salary*number/100; salary+=increase;//对比:double raise=this.salary*byPercent/100;        this.salary+=raise;

在java中,所有的方法都必须在类的内部定义,但并不代表他们是内联方法。是否将某个方法设置为内联方法是java虚拟机的任务。即时编译器会监事调用那些简洁、经常被调用,没有被重载以及可优化的方法。

封装的优点
简单的看一下下面的方法:

public String getName()    {        return this.name;    }    public double getSalary()    {        return this.salary;    }  public LocalDate getHireTime()    {        return this.hireTime;    }

这些都是典型的访问器方法。由于它们只返回实例域值,因此又称为域访问器。
将this.name,this.salary,this.hireDay域标记为public,以此来取代独立的访问器会不会更容易一些呢?
关键在于name是一个只读域。一旦在构造器中设置完毕,就没有任何一个办法对他进行修改,这样来确保name域不受到外界的破坏。

 private double salary;    private String name;   //String字符串型,为只读域,不可以修改    private LocalDate hireTime;

salary不是只读域(double不是只读),它可以用raiseSalary方法修改。

public void increaseSalary(double number)    {        double increase=salary*number/100;        salary+=increase;    }

特别是一旦这个值域出现了错误,只要调试这个方法就可以了。如果salary域是public的,破坏salary域值的因素就有很多。

 private double salary; public double salary;

在有些时候,需要获得或者设置实例域的值,因此,应该提供下面三项内容:
1、一个私有的数据域 private double salary;
2、一个公有的域访问器方法

//访问salary    public double getSalary()    {        return salary;    }

3、一个公有的域更改器方法:

//更改salarypublic void increaseSalary(double number)    {        double increase=salary*number/100;        salary+=increase;    }

某实例域满足以上三点,则对这个实例域来说,就可以构造、访问、更改了。
这样做的好处如下:
首先,可以改变内部实现,除了该类的方法之外,不会影响其他代码。例如,如果将存储名字name的域改为:
String firstName;
String laseName;
那么getName方法可以改为返回

private String firstName;private String laseName;public String getName(){        return firstName+“ ”+lastName;}//对比: private String name;public String getName()    {        return name;    }

这点,程序的其他部分完全不可见。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 最里面牙齿烂了怎么办 老公有外遇不承认怎么办 对老公疑心太重怎么办 当你发现老公出轨怎么办 发现自己老婆出轨了怎么办 笔袋密码忘记了怎么办 海关锁密码忘了怎么办 800度近视献了血怎么办 当老公有了外遇妻子该怎么办 妻子有外遇我该怎么办 喜欢拔粗的头发怎么办 小腿长水泡很痒怎么办 脚丫有水泡又痒怎么办 脚上起水泡怎么办很疼 脚上反复长水泡怎么办 高考没考上二本怎么办 车子被扣了60分怎么办 科目三挂了三次怎么办 装修到一半跑了怎么办 13岁自慰被发现怎么办 应用锁密码忘了怎么办 3d缺少dll文件怎么办 真三国无双6闪退怎么办 孙策死了大乔怎么办 30周羊水偏多怎么办 怀孕34周羊水多怎么办 孕34周羊水偏多怎么办 怀孕37周羊水少怎么办 电脑无法识别u盘怎么办 后厨地沟堵了怎么办 浅口鞋子不跟脚怎么办 机械键盘串键了怎么办 银龙突然不吃食怎么办 狗被蜈蚣咬了怎么办 婴儿被孕妇抱了怎么办 手机充电口坏了怎么办 油烫伤起泡破了怎么办 油烫伤后起泡了怎么办 被油烫伤泡破了怎么办 用油烫伤手起泡怎么办 手被烫伤了起泡怎么办