JAVA类与对象知识整理,Java基础知识 一 对象与类

(1)面向对象程序设计概述

面向对象的程序由对象组成,每个对象中包含对用户公开的特定功能部分和隐藏的实现部分。程序中的很多对象来自标准库,还有一些是自定义的。至于是自己构造对象,还是从外界购买对象完全取决于开发项目的预算和时间。但是,从根本上说,只要对象满足需求,就不必关心起功能的具体实现过程。

在OOP中,不必关心对象的具体实现,只要能够满足用户的需求即可。

①类

相关概念:类(class)、构造(construct)、实例(instance)、封装(encapsulation)、实例域(instance field)、方法(method)、状态(state)

②对象

对象的三个主要特性:

- 对象的行为(behavior)——可以对对象施加哪些操作,或可以对对象施加哪些方法?

- 对象的状态(state)——当施加这些方法时,对象如何响应?

- 对象标识(identity)——如何辨别具有相同行为与状态的不同对象?

③识别类

识别类的简单规则是,在分析问题的过程中寻找名词,而方法对应着动词。而在创建类时,哪些名词和动词是重要的完全取决于个人的开发经验。

④类之间的关系

在类之间,常见的关系有

依赖(“uses-a”),例如Order类使用Account类是因为Order对象需要访问Account对象查看信用状态;应尽可能地将相互依赖的类减至最少(低耦合);

聚合(“has-a”),例如一个Order对象包含一些Item对象;

继承(“is-a”)

注,表达类关系的UML符号

0818b9ca8b590ca3270a3433284dd417.png

(2)使用预定义类(已经定义好的类)

①对象与对象变量

相关概念:

构造器(constructor),一种特殊的方法,用来构造并初始化对象。

对象和对象变量的区别: Date deadline;

上面代码,定义了一个对象变量deadline,他可以引用Date类型的对象。但是,一定要注意:变量deadline不是一个对象,且目前也没有引用对象。此时,不能将任何Date方法应用于这个变量上。语句 String s=deadline.toString();

将产生编译错误。

一定要注意:一个对象变量并没有实际包含一个对象,而仅仅引用了一个对象。在Java中,任何对象变量的值都是对存储在另一个地方的一个对象的引用。new操作符的返回值也是一个引用。

可以将一个对象变量设置为null,表明这个对象变量目前没有引用任何对象。

③更改器方法与访问器方法

更改器方法:对实例域做出修改的方法;

访问器方法:仅访问实例域而不进行修改。

(3)用户自定义类

在一个源文件中,只能有一个共有类,可以有任意多数目的非公有类;

使用 javac 编译源代码时,如果包含main函数的类A所依赖的类B,且B跟A不在一个源文件中,编译器会自动查找类B所在的源文件进行编译;

构造器的性质:

构造器与类同名;

每个类可以有一个以上的构造器;

构造器可以有0个、1个或多个参数;

构造器没有返回值;

构造器总是伴随着new操作一起使用。

隐式参数与显示参数

方法用于操作对象以及存取对象的实例域。例如,方法: public void raiseSalary(double byPercent)

{

double raise = salary * byPercent / 100;

salary += raise;

}

将调用这个方法的对象的salary实例域设置为新值。例如, number007.raiseSalary(5);

它的结果将number007.salary域的值增加5%。具体说,这个调用将执行下列指令: double raise = number007.salary * byPercent / 100;

salary += number007.raise;

其中,raiseSalary方法有两个参数。第一个参数称为隐式参数(implicit),是出现在方法名前的Employee对象。第二个参数是位于方法名后面括号中的数值,这是一个显式参(explicit)数。

可以看到,显式参数是明显列在方法声明中的,例如double byPercent。隐式参数没有出现在方法生命中。

在每一个方法中,关键字this表示隐式参数。如果需要的话,可以使用下列方式编写raiseSalary方法: public void raiseSalary(double byPercent)

{

double raise = this.salary * byPercent / 100;

this.salary += raise;

}

这种方式可以将实例域与局部变量明显区分开来。

封装的优点:

在有些时候,需要获取或设置实例域的值。因此,应该提供下面三项内容:

一个私有的数据域;

一个公有的域访问器方法;

一个公有的域更改器方法。

这样做的要比提供一个简单的公有数据域复杂一些,但却有着明显的好处:

首先,可以改变内部实现,除了改类的方法之外,不会影响到其他代码;

然后,更改器方法可以执行错误检查,然而直接对域进行赋值不会进行这些处理。

警告:注意不要编写返回引用可变对象的访问器方法,这样会破坏封装性!(corejava,p113)

基于类的访问权限

一个方法可以访问所属类的所有对象的私有数据。

私有方法

在实现一个类时,由于公有数据非常危险,所以应该将所有的数据域都设置为私有的。对于方法而言,尽管绝大多数方法都被设计成为公有的,但是某些情况下,也可能将它们设计为私有的。有时,可能希望将一个计算代码划分为若干个独立的辅助方法。通常,这些辅助方法不应该成为公有接口的一部分,这是由于它们往往与当前的实现机制非常紧密,或者需要一个特殊的协议及一个特别的调用次序。最好将这样的方法设置为private的。

对于私有方法,如果改用其他方法实现了相应的操作,则不必保留原有的方法。因为,只要方法是私有的,类设计者就可以确定:它们不会被外部的其他类操作调用,可以将其删除。如果方法是公有的,则不能删除,因为其他的代码很可能依赖它。

final实例域

特点1:构造对象时必须初始化这样的域。也就是说,必须确保一个构造器执行之后,这个域的值被设置,并且在后面的操作中,不能够再对它做修改操作。

特点2:final修饰符大都应用在基本(primitive)类型域,或不可变类的域(如果类中的每个方法都不会改变其对象的状态,这种类就是不可变的类。例如,String类。)

(4)静态域与静态方法

①静态域(类域)

如果将域定义为static,则每个类只有一个这样的域。而每个对象对所有的实例域却都有自己的一份拷贝。静态域属于类,它不属于任何独立的对象(可以用来统计类实例化出来的对象的个数)。

②静态常量

静态变量使用较少,但静态变量比较常用。

③静态方法

静态方法,是一种不能向对象实施操作的方法,即没有隐式的参数的方法;

在下面两种情况下使用静态方法:

一个方法不需要访问对象状态,其所需参数都是通过显式参数提供(如,Math.pow())。

一个方法只需要访问类的静态域。

④工厂方法(???)

静态方法还有一种常见的用途。NumberFormat 类使用工厂方法产生不同风格的格式对象。

NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();

NumberFormat percentFormatter = NumberFormat.getPercentInstance();

double x = 0.1;

System.out.println(currencyFormatter.format(x));

System.out.println(percentFormatter.format(x));

为什么NumberFormat类不用构造函数完成这些操作呢?主要原因有两个:

无法命名构造器。构造器的名字必须跟类同名。但是,这里希望将得到的货币实例和百分比实例分别采用不同的名字;

当使用构造器时,无法改变所构造的对象类型。而Factory方法将返回一个DecimalFormat类对象,这是NumberFormat的子类。

⑤main方法

不需要使用对象调用静态方法。

同理,main方法也是一个静态方法。因此,它不对任何对象进行操作。事实上,在启动程序时,还没有任何一个对象。静态的main 方法将执行并创建程序所需的对象。

提示:每个类可以有一个main方法。这是一个常用于对类进行单元测试的技巧。

(5)方法参数

将参数传递给方法(或函数)的两种方式:

按值调用,表示方法接收的是调用者提供的值;

按引用调用,表示方法接收的是调用者提供的变量的地址。

一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。

Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。

方法参数公有两种类型:

基本数据类型(数字、布尔值);

对象引用。

在Java中,一个方法不可能修改一个基本数据类型的参数。而对象引用作为参数则不同,它使得方法可以借助对象引用的拷贝来修改对象参数状态(因为,对象引用及其拷贝同时引用同一个对象)。

总结,Java程序设计语言中方法参数的使用情况:

一个基本数据类型(即数值型和布尔型)作为参数传递给方法时,方法不能修改参数的值;

一个对象的引用值(地址)作为参数传递给方法时,方法可以借助该引用(地址)修改对应对象的状态;

一个对象的引用值(地址)作为参数传递给方法时,方法不能让引用(地址)重新引用一个新的对象。

(6)对象构造

①重载

一个类中有多个同名的方法,调用方法时通过传递的参数的类型来区分。

②域的默认初始化

如果在构造器中没有显式地给域赋予初值,那么就会被自动的赋予默认值:数值默认值为0,布尔值为false,对象引用为null。然而,这是一种极坏的编程习惯。

注:这是域与局部变量的主要不同点。方法中的局部变量必须明确地初始化。但是,如果没有初始化类中的域,则它将会被初始化为默认值(0,false或null)。

③无参构造器

如果在编写一个类时没有编写构造器,那么系统就会提供一个无参构造器。这个构造器将所有的实例域设置为默认值(0,false或null)。注意,只有当用户没有编写构造器时,系统才会提供一个默认的无参构造器。如果类中提供了至少一个构造器,但没有提供无参构造器,则在构造对象时如果没有提供参数就会被视为不合法。

④域的显式初始化

由于类的构造方法可以重载,所以可以采用多种形式设置类的实例域的初始状态。这是一种很好的设计习惯。

可以在类的定义中,直接将一个值赋给任何域。例如: class Emplyee {

private String name = "";

...

}

在执行构造器之前,先执行赋值操作。当一个类的所有构造器都希望把相同的值赋给某个特定的实例域时,这种方式特别有用。

初始值不一定是常量。下例,可以调用方法对域进行初始化。 class Emplyee {

private static int nextId;

private int id = assignId();

private static int assignId() {

int r = nextId;

nextId++;

return r;

}

}

⑤参数名

推荐风格为:

public Emplyee(String name, double salary) {

this.name = name;

this.salary = salary;

}

⑥调用另一个构造器

关键字this的另一种用法:可以在构造器中调用同一个类的另一个构造器。

好处:对公共的构造器代码部分只编写一次。

⑦初始化块

初始化数据域的三种方法:

在构造器中设置值

在声明中赋值

初始化块

静态域初始化:

可以通过提供一个初始化值,或使用一个静态的初始化块来对静态域初始化;如果对类的静态域初始化的代码比较复杂时,可以使用静态的初始化块。

(7)包

作用:

方便类的组织;

确保类名的唯一性:在两个不同的包中,可以有相同名字的类。

①类的导入

一个类可以使用所属包的所有类,以及其他包的公有类(public class)。

访问其他包公有类的两种方式:

第一种,在每个类名之前添加完整的包名;

第二种,import关键字导入一个特定的类或整个包。

②静态导入

import语句不仅可以导入类,还可以导入静态方法和静态域。

import static java.lang.System.*;

/** * Created by bmi-xiaoyu on 2017/5/22. */

public class Test1 {

public static void main() {

out.println("".toString()); //使用静态方法时不用加类名

}

}

import 还可以导入特定的方法或域:

import static java.lang.System.out;

④包作用域

对于类、方法或变量,标记为public的部分可以被任意的类使用;标记为private的部分只能被定义它们的类使用;如果不指定public或private,则这个部分可以被同一个包中的所有方法访问。

0818b9ca8b590ca3270a3433284dd417.png

(8)类路径

为了使类能够被多个程序共享,可以采用以下方式中的一种:

把类放在一个目录中;

将JAR文件放在一个目录中;

设置类路径(class path)。类路径是所有包含类文件的路径的集合。

(9)文档注释

详细介绍了,如何利用JDK中提供的 javadoc 工具生成注释。

(10)类设计技巧

应用这些技巧会使得设计出来的类更具有OOP的专业水平:

一定要保证数据私有。

一定要对数据初始化。

不要在类中使用过多的基本类型。

不是所有的域都需要独立的域访问器和域更改器。

将职责过多的类进行分解。

类名和方法名要能够体现它们的职责。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值