对象与对象变量:

要想使用对象,就必须首先构造对象,并指定其初始状态,然后,对对象应用方法。

在Java中,使用构造器构造新实例。构造器是一种特殊的方法,用来构造并初始化对象。

在实际开发中,通常需要将对象存放在一个变量中来达到多次使用的目的。

在这里,birth指向了Date对象的存储的地方的引用。

Date birthday = new Date();

在对象与对象变量直接存在着一个重要的区别,例如:

Date deadline;  //deadline dosen't refer to any object;

定义了一个对象变量,它可以引用Date类型的对象,但是,一定要认识到:变量deadline不是一个对象,实际上也没有引用一个对象。并且不能用任何Date方法应用与这个变量上

s = deadline.toString(); // not yet

在这里,将会产生编译错误。

首先,必须初始化变量deadline,可以用新构造的对象初始化,也可以引用一个已存在的变量。

deadline = new Date() //新构造对象
//
//或者
Date birthday = new Date();
deadline = birthday; //引用一个已存在对象  

当引用一个已存在的变量时,两个变量引用同一个对象:

在Java开发中,一定要认识到,一个对象变量并没i月实际包含一个对象,而仅仅使用一个对象,任何对象变量的值都是对存储在另外一个地方的一个对象的引用。

 

 

 

构造器:

首先来看一个Employee类:

class Employee
{
// instance fields
private String name;
private double salary;
private LocalDate hireDay;
// constructor 构造器
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
hireDay = LocalDate.of(year, month, day);
}
// a method
public String getName()
{
return name;
}
// more methods
. . .
}

该类的构造器与类同名,在构造Employee类的对象时,构造器会运行,并将实例初始化为所希望的状态。

例如,当使用下面代码实例化时:

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

将会把实例域设置为:

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

构造器与其他方法有一个区别,即构造器伴随着new操作符被调用并且没有返回类型,而不能通过一个对象调用构造器,如下将会产生编译错误。

james.Employee("James Bond", 250000, 1950, 1, 1) // ERROR

重载:

一个类可以拥有多个构造器。

如果在一个类中,拥有多个方法,每个方法具有相同的名字,不同的参数,便产生了重载。编译器必须挑选出具体执行那个方法。

通常,多个具有相同名字不同参数的方法,是通过它们的签名来辨识的。

什么是方法的签名?

一个方法的签名即为它的方法名称,以及参数类型。注意,返回类型并不属于一个方法的签名!也就是说,不能具有相同名字,相同参数,而返回类型不同的两个方法。

 

默认域初始化:

如果在构造器中没有显式的给域赋予初始值,那么域会被自动地赋予默认值,数值为0,布尔值为false,对象引用为null。

这是域与局部变量的主要不同点。局部变量必须明确地初始化。

 

无参数的构造器:

很多类都包含一个无参数的构造函数,对象由构造函数创建时,状态会被设置为适当的默认值,如下为Employee类的无参数构造函数:

public Employee()
{
name = "";
salary = 0;
hireDay =new Date();
}

如果一个类没有编写构造器的话,那么系统就会提供一个无参数构造器。

 

调用另一个构造器:

如果构造器的第一个语句形如this(...),这个构造器将会调用同一个类的另一个构造器,下面是一个典型的例子:

public Employee(double s){
this("Employee ",s);
}

当调用new Employee(60)时,Employee(double)构造器将调用Employee(String,double)构造器。

 

初始化块:

 通常,初始化数据域有三种方法,一种是在构造器设置,一种是在声明中赋值,还有一种是初始化话块,只要构造类的对象,这些块就会被执行。

class Employee
{
private static int nextId;
private int id;
private String name;
private double salary;
// object initialization block 初始化块
{
id = nextId;
nextId++;
}
public Employee(String n, double s)
{
name = n;
salary = s;
}
public Employee()
{
name = "";
salary = 0;
}
. . .
}

 由于初始化数据域有多种途径,所以可能会有些混乱,下面是调用构造器的具体处理步骤:

1.所有数据域被初始化默认值。

2.按照类声明中出现的次序,依次执行所有域初始化语句和初始化块。

3.如果构造器第一行调用了第二个构造器,则执行第二个构造器的主体。

4.执行这个构造器的主体。

 

不要编写返回引用可变对象的访问器方法:

例如:

class Employee
{
private Date hireDay;
. . .
public Date getHireDay()
{
return hireDay; // Bad
}
. . .
}

 

这样会破坏封装性,即可以不通过Hireday的设置器方法就能改变Hireday,具体如下代码:

Employee harry = . . .;
Date d = harry.getHireDay();
double tenYearsInMilliSeconds = 10 * 365.25 * 24 * 60 * 60 * 1000;
d.setTime(d.getTime() - (long) tenYearsInMilliSeconds);
// let's give Harry ten years of added seniority

出错的原因即为d和harry.hireDay引用同一个对象,参见图:

实际上,返回对象应对其进行克隆,并返回该克隆对象。

 

 

 

 

final实例域:

可以将实例域定义为final,构建对象时必须初始化这样的域,也就是说,确保在每一个构造器执行之后,这个域的值被设置,并且在后面的从早中,不能够在对它进行修改。

通常,不推荐是哦那个final修饰符应用于可变的类,如下:

private final Date hiredate;

这仅仅意味着,存储在hiredate变量的对象引用不可变,也就是说永远指向同一个对象引用,但任何方法都可以对hiredate引用的对象调用setTime更改器来改变该对象。

 

静态域与静态方法:

如果将域定义为static,每个类中只有一个这样的域。而每一个对象对于所有的实例域却都有一份自己的拷贝。静态域是所有对象共享的,如这里给Employee类添加一个实例域id和一个静态域nextId:

class Employee
{
private static int nextId = 1;
private int id;
. . .
}

换句话说,如果有1000个Emplyee对象,那么就有1000个id实例域,但却只有一个nextId静态域。即使没有实例对象时,静态域也是存在的,它是属于类,而不是属于对象。

静态方法同理。

 

方法参数:

 Java中的参数是一种值引用。

首先,观察一下基本数据类型(数字、布尔值)。

public static void tripleValue(double x) // doesn't work
{
x = 3 * x;
}
double percent = 10;
tripleValue(percent);

当我们将percent作为参数给一个方法时,经过执行后,percent本身并没有改变,这个很容易理解。

接下来看一下对象引用:

public static void tripleSalary(Employee x) // works
{
x.raiseSalary(200);
}

当调用如下语句时:

harry = new Employee(. . .);
tripleSalary(harry);

具体的操作过程如下:

1.x被初始化harry值的拷贝,这是一个对象的引用。

2.raiseSalary方法应用于这个对象的引用,x和harry同时引用的那个Employee对象的薪金提高了200%。

3.方法结束后,参数变量x不再使用。当然,对象变量harry继续引用那个薪金增3倍的对象。

看到这里,或许会认为Java的对象参数是引用调用,实际上,并不是。

依然是按值调用,传给tripleSalary函数的实际上是harry值的拷贝,而harry值指向了一个对象引用,所以x也指向了该引用,所以才会引起变化。

可以通过下面这个例子得出结果:

public static void swap(Employee x, Employee y) // doesn't work
{
Employee temp = x;
x = y;
y = temp;
}

如果Java是按引用调用的话,那么执行下面语句后,a与b应该互换。

Employee a = new Employee("Alice", . . .);
Employee b = new Employee("Bob", . . .);
swap(a, b);
// does a now refer to Bob, b to Alice?

但在测试中,并没有互换,所以传入的实际上是a,b的拷贝,也就是一个对象引用,这个方法交换的是这两个拷贝。

最终,函数结束时,变量x,y被丢弃了,原来的ab对象变量依然引用之前的对象。

Java核心技术 对象与类的更多相关文章

  1. Java常见对象Object类中的个别方法

    Java常见对象Object类 public int hashCode() : 返回该对象的哈希码值. 注意:哈希值是根据哈希算法计算出来的一个值,这个值和地址值有关,但是不是实际地址值.你可以理解成 ...

  2. 快乐编程大本营【java语言训练班】 6课:用java的对象和类编程

    快乐编程大本营[java语言训练班] 6课:用java的对象和类编程 第1节. 什么是对象和类 第2节. 对象的属性和方法 第3节. 类的继承 第4节. 使用举例:创建类,定义方法,定义属性 第5节. ...

  3. Java的对象与类,继承

    Java的对象与类,继承 题目1.Java类的建立与使用 设计一个用来描述汽车的类,使用类的非静态成员变量来表示汽车的车主姓名.当前的速率和当前方向盘的转向角度,使用类的非静态成员方法来表示改变汽车的 ...

  4. 你真的了解JAVA中对象和类、this、super和static关键字吗

    作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 目录 Java对象究竟是什么? 创建对象的过程 ...

  5. (转)java 多线程 对象锁&类锁

    转自:http://blog.csdn.net/u013142781/article/details/51697672 最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不 ...

  6. Java基础-对象与类

    面向对象程序设计概述 面向对象的程序设计(简称OOP)时当今主流的程序设计范型,已经取代了"结构化"过程化程序设计开发技术,Java是完全面向对象的. 类 类设计构造对象的模板或蓝 ...

  7. Java 2-Java 对象和类

    Java 对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 消息解析 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例,有状态和行为. ...

  8. Java 的对象和类

    Java 是一种面向对象的语言.作为一个面向的语言,Java 具有面向对象的特性,Java 能够支持下面的一些基本概念 − 多态(Polymorphism) 继承(Inheritance) 封装(En ...

  9. mongodb中Gson和java##Bean对象转化类

    此类使用感觉比较繁琐, 每个字段加注解才可以使用, 不如mongoTemplate使用方便, 但如果使用mongo客户端的话, 还是比手动拼接快一点, 所以贴在这儿 package com.iwher ...

随机推荐

  1. vim配置文件.vimrc

    20171127备份 syntax on "自动语法高亮 set number "显示行号 set autoindent "回车后自动缩进 set tabstop=4 & ...

  2. ES6 generators in depth 一(译)

    今天在学习redux-saga时,外部链接推荐了这篇文章ES6 generators in depth,所以翻译的同时也可以加深一下对Generator的理解. 这里对原文一些只能在高版本现代浏览器使 ...

  3. (转)jira7.2安装、中文及破解

    转自:http://www.cnblogs.com/ilanni/p/6200875.html 本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanni ...

  4. Apache Tomcat Eclipse Integration

    An Illustrated Quick Start Guide Apache Tomcat makes hosting your applications easy. The Eclipse IDE ...

  5. Python核心团队计划2020年停止支持Python2,NumPy宣布停止支持计划表

    Python核心团队计划在2020年停止支持Python 2.NumPy项目自2010年以来一直支持Python 2和Python 3,并且发现支持Python 2对我们有限的资源增加了负担:因此,我 ...

  6. Shell条件测试和流程控制-4

  7. Windows Server2012 搭建域错误“本地Administraor账户不需要密码”

    标签:MSSQL/SQLServer/域控制器提升的先决条件验证失败/密码不符合要求 概述 在安装WindowsServer2012域控出现administrator账户密码不符合要求的错误,但是实际 ...

  8. HNOI2019退役记

    退役 警告. 今年虽然我没有变强, 但是还是比去年强一点(去年树形dp都不会). Day0 明天就是省选了,晚上22:13还没有睡觉,真的是状态不好. 打了一下LCT的板子,发现终于理解了...(这叫 ...

  9. HTML学习一_网页的基本结构及HTML简介

    HTML网页的基本结构 ```angular2html<!DOCTYPE html> 声明为 HTML5 文档<html> 元素是 HTML 页面的根元素<head> ...

  10. HTML5与CSS3权威指南笔记案例1

    第1章 <!DOCTYPE html> <meta charset = "UTF-8"> <title> Search </title&g ...