Java 学习记录二:OOP入门

OOP基础

class是构造对象的模板或者说蓝图。由类构造的对象称为类的实例(instance)。
类封装是与对象有关的一个重要概念。从形式上来看,封装不过是将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式。对象中的数据称为实例域,操纵数据的过程称为方法。对于每个特定的类实例,都有一组特定的实例域值。这些值的几何就是这个对象的当前状态。无论何时,只要想对象发送一个消息,它的状态就有可能发生改变。
实现封装的关键在于,绝对不能让类中的方法直接地访问其他类的实例域。程序仅仅通过对象的方法与对象数据进行交互。封装给对象赋予了黑盒特征,这是提高重用性和可靠性的关键。这意味着一个类可以全面地改变存储数据的方式,只要仍旧使用同样的方法操作数据,其他的对象就不会知道或介意所发生的变化。
OOP的另一个原则会让用户自定义Java类变得轻而易举:可以通过扩展一个类来建立一个新的类。
扩展一个已有的类时,新类就会具有所扩展的类的全部方法和属性。在新类中,只需要提供适用于这个新类的新方法和数据域就可以了。通过扩展一个类来建立新的类的过程称为继承。
传统的过程化程序设计,必须从顶部的main函数开始编写程序。在OOP程序设计时没有所谓的顶部,方法是:首先从设计类开始,然后再往每个类中添加方法

对象

对象有三个主要特性:

  1. 对象的行为——可以对对象施加那些操作,或者哪些方法。
  2. 对象的状态——当施加那些方法时,对象如何相应。
  3. 对象标识——如何比阿尼额具有相同行为与状态的不同对象。

同一个类的所有对象实例,由于支持相同的行为而具有家族式的相似性。对象的行为是用可调用的方法定义的。
此外,每个对象都保存着描述当前特征的信息。这就是对象的状态。对象的状态可能会随着时间而发生改变,但是这种改变不是自发的。对象状态的改变必须通过调用方法实现。
但是,对象的状态并不能完全描述一个对象。每个对象都有一个唯一的身份。例如,在一个订单处理系统中,任何两个订单都存在着不同之处。即使所订购的货物完全相同也是如此。需要注意的是,作为一个类的实例,每个对象的标识永远是不同的,状态也常常存在着差异。

预定义类

Java中,没有类就无法做任何事情。也不是所有的类都具有面向对象特征。

对象与对象变量。

要想使用对象,就必须首先构造对象,并制定其初始状态。然后对对象应用方法。
在Java中,使用构造器构造新实例。构造器是一种特殊的方法,用来构造并初始化对象。

Date类

构造器的名字应当与类名相同:new Date()
这个表达式构造了一个新对象。这个对象被初始化为当前的日期和时间。
我们需要储存这个构造出来的对象:Date birthday = new Date();
注意对象变量和对象是不同的,对象变量可以引用变量,在引用变量之前它什么都不是。
可以显式地将对象变量赋值为nullDate deadline = null;

GregorianCalendar类

在前面的例子中,已经使用了Java类库的Date类。Date类的实例有一个状态,即特定的时间点
尽管在使用Date类时不必知道这一点,但时间是用距离一个固定时间点的毫秒数(时间戳)来表示的。
但是Date类所提供的日期处理并没有太大的用途。Java类库的设计者认为,通用日期表示法只适用于我们一般的固有习惯。
类库设计者决定将保存时间与给时间点命名分开。所以Java类库分别包含了两个类,一个是表示时间点的Date类,一个是日历表示法GregorianCalendar类。将时间与日历分开是一种很好的面向对象设计。
通常,最好使用不同的类表示不同的概念。
GregorianCalendar类中有更多的构造器和方法。
可以提供年月日来构造一个表示某个特定日期午夜的日历对象:new GregorianCalendar(1998, 11, 31)
比较怪异的是,月份从0开始计数。为了清晰,可以用常量:new GregorianCalendar(1998, Calendar.DECEMBER, 31)
还可以设置时间:new GregorianCaldendar(1998, 11, 31, 23, 59, 59)

自定义类

从构造器开始

可以看到,构造器与类同名。在构造对象时,构造器会运行,以便将对象初始化为所希望的状态。

  • 构造器与类同名。
  • 每个类可以有多个构造器。
  • 构造器可以有0、1或者多个参数。
  • 构造器没有返回值。
  • 构造器总是伴随着new操作一起调用。

隐式参数和显式参数

方法用于操作对象和存取他们的实例域。

class a{
    int x;
    void b(int y){
        int x = y;
        this.x = x;
    }
}

上面是一个类的示例,类中有一个变量x,方法b中也有,this关键字就用来调用类中的参数,称为隐式参数。

静态域和静态方法

static是静态修饰符。

静态域

如果将域定义为static,每个类中只有一个这样的域。而每个对象对于所有的实例域却都有自己的一份拷贝。
static域是属于类的,所有对象共用一个。

静态方法

静态方法是不能向对象实施操作的方法。
可以认为static方法是没有this参数的方法。
使用静态方法主要在以下两种情况:

  1. 一个方法不需要访问对象状态,其所需的参数都是通过显示参数提供。
  2. 一个方法只需要访问类的静态域。

工厂方法

静态方法还有一种常见用途:采用不同的工厂方法产生不同风格的实例。
使用工厂方法主要有以下两种情况:

  1. 无法命名构造器,构造器的名字必须与类名相同。但是,这里希望得到的货币实例和百分比实例采用不同的名字。
  2. 当使用构造器时,无法改变所构造的对象类型。

方法参数

一般传参有两种形式:传引用、传值。
Java中总是采用按值调用的方式。方法得到的是所有参数值的一个拷贝。
特别地,方法不能修改传递给它的任何参数变量的内容。
然而,方法参数共有两种类型:基本数据类型、对象引用。
一个方法不能修改一个基本数据类型的参数,而对象引用作为参数就不同了。
可以在方法中修改对象的状态。
但这不是说对象引用可以改变对象变量的值,对象采用的不是引用调用,而是值传递。

对象构造

重载

多个方法有相同的名字,不同的参数列表,就产生了重载。
编译器根据方法的参数类型来判断具体执行哪个方法。

默认域初始化

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

无参数的构造器

如果再编写一个类是没有编写构造器,那么系统就会提供一个无参数构造器。
如果类中提供了至少一个构造器,但是没有提供无参数的构造器,则在构造对象时如果没有提供参数就会被视为不合法。

显示域初始化

由于类的构造方法可以重载,所以可以采用多种形式设置类的实例域的初始状态。
确保不管怎么样调用构造器,每个实例域都可以被设置为一个有意义的初值。
在执行构造器之前,先执行复制操作。当一个类的所有构造器都希望把相同的值富于某个特定的实例域是,这种方法特别有用。

Java使用包(package)来将类组织起来。借助包可以方便地组织自己的代码,并将自己的代码与别人提供的代码库分开管理。
标注你的Java类库分布于多个包中,包括java.lang``java.util``java.net等。标准的Java包都处于java``javax包层次中。
试用包的主要原因是确保类名的唯一性。加入两个程序员建立了同样类名的类,只要将这些类放置在不同的包中,就不会发生冲突。

类的导入

一个类可以使用所属包中的所有类,和其他包中的公共类。我们可以曹勇两种方式访问另一个包中的所有公共类。
第一种方式是在每个类名之前添加完整的包名:java.util.Date today = new java.util.Date()
这显然很繁琐。
更简单更常用的是使用import语句。
注意,只能用*导入一个包,不能导入所有包。

将类放入包中

要想将一个类放进包中,就必须将包的名字放在源文件的开头。
如果没有在源文件中放置package语句,这个源文件中的类就被放置在一个默认包中。默认包没有名字。
我们应当将包中的文件放到与完整的包名匹配的子目录中。

包作用域

前面已经接触过访问修饰符publicprivate。标记为public的部分可以被任意类使用,标记为private的部分职能被定义它们的类使用。
如果没有指定,这个部分可以被同一个包中的所有方法访问。

类路径

类的路径必须与包名匹配。
另外,类文件也可以存储在JAR文件中,在一个JAR文件中,可以包含多个压缩形式的类文件和子目录。这样既可以节省又可以改善性能。
在程序中用到第三方的库文件时,通常会给出一个或多个需要包含的JAR文件。JDK也提供了许多的JAR文件,例如,在jre/lib/re.jar中包含数千个类库文件。

为了使类能够被多个程序共享,需要做到以下几点:

  1. 把类放到一个目录中。需要注意,这个目录是包树状结构的基目录。如果希望将一个类添加到其中,这个类文件就必须位于子目录中。
  2. 在JAR文件放在一个目录中。
  3. 设置类路径,类路径是所有包含类文件的路径的集合。

在UNIX环境中,类路径中的不同项目之间采用冒号分隔。
而Windows环境中,类路径中的不同项目之间采用分号分隔。
类路径包括:

  • 基目录
  • 当前目录
  • JAR文件

文档注释

JDK包含一个很有用的工具,叫做javadoc,它可以由源文件生成一个HTML文档。
如果在源码中添加以专用的定界符开始的注释,那么可以很容易地生成一个看上去具有专业水准的文档。
这是一种很好的方式,因为这种方式可以将源码和注释保存在一个地方。如果将文档存入一个独立的文件中,就可能会随着时间的推移,出现代码和注释不一致的问题。

注释的插入

javadoc实用程序从下面几个特性中抽取信息:

  • 公用类和接口
  • 公有的和受保护的构造器和方法
  • 公有的和受保护的域

应该为上面几部分编写注释。注释应该放置在所描述的特性的前面。注释以/**开始,*/结束。
每个/**...*/文档注释在标记之后紧跟着自由格式文本。标记由@开始。
自由格式文本的第一句应该是一个概要性的句子。javadoc实用程序自动地将这些句子抽取出来形成概要页。

类设计技巧

下面简单记录一些OOP的类设计技巧。

1. 一定要保证数据私有

这是最重要的;绝对不要破坏封装性。有时候,需要编写一个访问器方法或更改器方法,但是最好还是保持实例域的私有性。
很多惨痛的经验告诉我们,数据的表示形式很可能会改变,但它们的使用方式却不会经常发生变化。当数据保持私有时,它们的表示形式的变化不会对类的使用者产生影响。

2. 一定要对数据初始化

Java不对局部变量进行初始化,但是会对对象的实例域进行初始化。最好不要依赖于系统的默认值,而是应该显式地初始化所有数据。
具体的初始化方式可以是提供默认值,也可以是在所有构造器中设置默认值。

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

就是说,用其他的类代替多个相关的基本类型的使用。这样会使类更加易于理解且已与修改。
例如,我们可以用一个新的类来替换类中的一些实例域。
这样可以更加容易地理解和处理变量。

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

或许,需要获取或设置雇员的薪资。而一旦构造了雇员对象,就应该禁止更改雇用日期,并且在对象中,常常包含一些不希望别人获得或设置的实例域。

5. 将职责过多的类进行分解

这样说似乎有点含糊不清,究竟多少算是“过多”?
每个人的看法不同,但是如果明显地可以将一个复杂的类分解为两个更为简单的类,就应该将其分解。

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

与变量应该有一个能够反映其含义的名字一样,类也应该如此。
命名类名良好的习惯是采用一个名词、前面有形容词修饰的名词或动名词修饰的名词。
对于方法来说,习惯是访问器方法用小写get开头,更改器方法用小写set开头。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容