达内学习心得:精心总结的面向对象

时间:2019-05-13 11:07:46下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《达内学习心得:精心总结的面向对象》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《达内学习心得:精心总结的面向对象》。

第一篇:达内学习心得:精心总结的面向对象

达内学习心得:精心总结的面向对象

参赛学员:方钱有

获奖奖项:二等奖

什么面向对象:

个人分析觉得:在程序设计里,面向对象是一种相对说法,相对于面向过程而言的;

面向“对象“:即重点在于“对象”;而面向过程:则重点在于“过程”,简单说:就是我我们看待事物在眼光上注重点不一样;比如说:我们评判一个女孩漂亮与否,有的人看重外表,有的人则看重“心灵”,只是侧重点不一样。

举个例子:把大象装进冰箱!

面向过程面向对象(注重一系列动作即过程)(注重动作所操作的承受者[“对象”])

“打开”冰箱“冰箱”打开“装入”大象“大象”装入“关闭”冰箱“冰箱”关闭

类:通俗的说类就是“一类事物的简称”,并且这些事物至少具有一点“共同的”特征.比如说:动物就是一个类

对象:就是某一类中一个具体的(就是可以具体描述出来的)东西,比如:动物(类)里的“狗”就是一个对象。(个人觉得对象相对于类而言的,因为狗又可以分好多种,‘狗’相对于‘哈士奇’是一个类,‘哈士奇’是‘狗’类的一个具体对象)

在生活中就拿描述汽车来说,我们都知道汽车都有4个轮子; 都有跑的功能 可以如下描述:

类汽车

属性: 4个轮

功能: 跑

那么怎么在Java中描述汽车这类呢?

class car{

int wheel=4;//属性: 4个轮

void run(){//方法(功能): 跑

System.out.println(“是汽车都会跑”);

}

}

那么可见“出租车”应当是“汽车”这类的一个具体化(实实在在的例子即“实例”)对象,那自然出租车也就具备了汽车这类所具备的“共有”属性功能!

如何创建一个出租车对象呢?java中通过new关键字来创建一个类的实例即对象,也叫类的实例化,就是把类具体化成一个实例嘛!

格式:类名对象名 =mew 类名()

Cartexi =newCar();

创建了“出租车”对象(实例)之后那么它也就有了如下“自己”的属性和功能。

int wheel=4;//属性: 4个轮

void run(){//功能: 跑

System.out.println(“我是出租车我也会跑”);

}

我们如何来访问对象中的它自己的属性和方法呢?

格式:对象.属性;对象.方法名();这一点也验证了面向对象编程的侧重点在于“对

象”上;

texi.wheel;texi.run()

*******************************************************************************

*******************************************************************************

*******************************************************************************

1.封装:

从字面可以解读为将东西封起来再装好。要想拿到里面的东西就得有相应的方法打开,才能

拿到。

举例来说:一个房间的门如果没有上锁,那么大家都可以进去拿东西,但现在我们不想让谁

都进来拿东西,我们可以将房门上锁,只对外提供一把钥匙,只有有钥匙的人才能进来,这

就是“封装”现象!

在java程序中,“封装”现象如何实现呢?

可以这样实现:将类中的一些属性和方法用private关键字修饰,将他们“私有化(即不对

外直接公开)”,使外部其他类不能通过创建该类对象或通过类名直接访问这些属性和方法;

只对外提供公有的方法,外部其他类必须通过该类对外提供的公有方法来访问该类的相应成员;例如:

class Person{

private String name;//将name属性私有化(封装)[相当于了上锁]使外部其他类不能直

接访问到

public SetName(String name){//对外提供公有方法(相当于房门钥匙)供外部其他类访问

到本类属性

this.name=name;

}

}

2.继承:

从字面来说继承就是子父类关系的简称,就是儿子(女儿也行,好吧)会继承老爸的一些属性和行为

在java中如何描述继承关系呢?

注意:第一得知道在java中继承是类与类之间或者是接口与接口之间才有继承关系;

通过extends关键字来描述继承关系

例如:老爸这个类

class Dad{

String sex=man;

void smoke(){

System.out.println(“老子会抽烟!”);

}

}

那么我们怎么来让儿子这个类继承老爸这个类呢?

class Son extends Dad{//通过extends关键字儿子这个类就继承老爸这个类了

String name;//定义自己的属性

String sex=man;//继承过来的属性,无须再定义,这里写出来是为了好理解

void smoke(){//继承过来的方法,无须再定义,这里写出来是为了好理解

System.out.println(“老子会抽烟!”);

}

void playBall(){//定义自己的方法

System.out.println(“儿子即会打球又会抽烟!”);

}

void somke(){//重写的方法

System.out.println(“我不抽20块以下的烟”);

}

void smoke(int n){//重载的方法

System.out.println(“我抽了+n+”年的烟了“);

}

}

那么具有继承关系的两个类有什么特点呢?

1)子类会将父类的属性和方法继承过来,当然子类也可以自己定义的属性和方法

2)当子类自己定义的方法和父类继承过来的方法相同时会发生“重写“现象!

3)父类用private关键字私有的方法是不能被继承的!

4)子类可以使用super访问父类的属性和方法

5)子类通过重写父类方法,修改父类的功能

6)子类构造器一定调用父类的无参构造器

7)构造器不能继承

3.多态:

字面意思就是多种形态,也就是说一种事物同时局部多种形态.注意:要出现多态情况,那么类和类之间一定得是继承关系,或者类和接口是实现关系

我觉得:在java中多态是相对于一个对象而言的,就是父类型引用变量引用子类对象,并

且父类型引用变量可以接受不同子类的对象

例如:拿上面的举例

Dad uncle=new Son();父类引用变量uncle即具备Son类的成员又具备父类的成员;这也称

为“向上造型”;

多态时的特点

1)多态时访问成员变量,如uncle.name;

编译时看等号左边,父类有该成员变量则编译通过,否则编译出错!

运行时也看等号左边,有则运行结果

2)多态时访问方法,如uncle.smoke()

编译时看等号左边,父类有该成员方法则编译通过,否则编译出错!

运行时看等号右边,父类有该方法,子类没有该方法执行父类方法;父类有该方法,子类也

有该方法执行子类方法

3)多态时访问静态方法

编译运行都看等号左边

*******************************************************************************

*******************************************************************************

*******************************************************************************

*********************

4.抽象(有争议):

什么是抽象?

抽象就是不具体。

一般我们把不能具体描述的东西约定俗成为“抽象”的东西。例如:我们说一个人长得很

“抽象”,n你想你能具体形容描述出来么?

在JAVA中如何描述抽象这个概念呢?

我觉得在java中抽象类是由抽象方法而衍生出来的,为什么呢?

因为Java规定一个类中定义了抽象方法那这个类就跟着必须定义为抽象类,而不是因

为先定义抽象类再跟着规定抽象类中的方法必须是抽象的,可能最后理解的结果是一样的但

性质是不一样的(个人理解)简单说:就是有抽象方法的类一定是抽象类,但是抽象类中不

一定都是抽象方法,也可以有具体方法。

首先就是当我要在一个类定义一个方法时,暂时我不知道该方法具体功能是什么;等我想好

了我在用他实现一个功能时我再具体描述他功能,这样我们就可以将这个方法用abstract关

键字修饰定义为抽象方法

(还有一点也就是什么时候定义抽象类的?也可以说抽象类是向上抽取而来的,就是几个类

据有共同的属性和方法,不想每个类都定义一次,那么定义一个公有类(即抽象类)其他类

只要继承抽象类再重写方法就行!)

例如:我有一百块钱,现在我不知道怎么用,等我想好了在具体怎么用!

abstract class Money{//因为有了抽象方法所以必须定义为抽象类

public abstract void buySomthing();//现在不知道怎么用,那就把它的功能代码体去掉

}

//现在我饿了,想买东西吃了,我就知道怎么用了

class Hungry extends Money{

void buySomething(){

System.out.println(”我饿了,现在我要买东西吃!“)

}

}

抽象类的特点

1)抽象类不能实例化

2)抽象类可以继承抽象类

3)继承抽象类必须得重写抽象方法

5.抽象类,接口,普通类 的不同点和相同点?

1)不同点:

普通类接口抽象类

可以直接实例化对象不可以直接实例化对象不可以直接实例化对象

可以定义任何成员只能定义抽象成员方法和常量成员

方法必须定义为抽象其他和普通类相同

可以被继承类可以实现接口,且可以实现多个接口可以被继承

接口可以继承多个接口抽象类有构造方

法,接口中不能有

抽象类有普通成员变

量,接口中没有

抽象类可以有非抽象方

法,接口中不能有

抽象类可以用public、protected修饰,接口中只能public(默认public)

抽象类包含静态方法,接

口中没有

接口中的变量只能是

public static final,抽象类中可以是任意类型修饰

2)相同点:都可以用于描述(封装)事物的,内部类分为哪几种?分别如何创建对象?

分为 局部内部类,匿名内部类...3种

1)外部类名.内部类名 对象名=new 外部类名().new 内部类名()

2)外部类名.内部类名 对象名=外部类名.new 内部类名()

3)....不记得了第3种

匿名内部类

二、集合集合的定义?

集合:用来保存一组数据的数据结构

集合的父接口,实现接口,实现类,实现类的常用方法是什么?(建议以树状图画出来,便

于加深印象)。

Collectionlistset

ArraylistLinkedListHashSet

TreeSet

1.List集合List集合的特征是元素可重复且有序 ;我们可以把他看成是一个动态数组,一般通过下标

访问

ArrayList和LinkedList最常用的两个子类实现

1)list可以使用for循环遍历

for(int i=;i

list.get(i);

}

2)list的浅层复制

调用ArraryList.clone()方法

注意:不能使用list.clone(),clone()方法是Object类的方法,list是接口是不能继承Object类的2.Set集合:

不重复且无序集

遍历set只能迭代器,用迭代器遍历集合遵循的操作原则:先问后取。问一次取一次。Iterator it=set.iterator();

while(it.hashnext()){

E e=it.next();

}

3)map表

Map存储数据使用key-value(键-值)对的形式存储数据的。

对于Map而言,要求key值是唯一的。value值可以重复

获取数据时,使用key可以获取其对应的value

遍历map有3种方法

1)遍历key

Set keySet = map.keySet();

for(String key:keySet){

System.out.println(”key:“ + key);

//可以根据每一个key获取其对应的value值

int value = map.get(key);

2)遍历value

Collection values = map.values();

Iterator it = values.iterator();

while(it.hasNext()){

int value = it.next();//不能采用 map.next()

System.out.println(”value:“ + value);

注意:通过迭代器在遍历集合的过程中,不能通过集合(即不能采用 map.next())去改变集合元素数量

3)遍历键值对

Set> entries= map.entrySet();

for(Entry entry : entries){

//获取一组键值对的键和值

String key = entry.getKey();

int value = entry.getValue();

System.out.println(key + ”=" + value);

Collection接口方法的定义

这里我主要列举 Iterator iterator()方法的使用

Collection提供的方法 Iterator iterator()方法来获取迭代器

Iterator是一个接口,定义了遍历集合应有的方法。

使用迭代器遍历集合遵循的操作原则:先问后取。问一次取一次。问:boolean hashNext()

取:Object next()

迭代器可以将取出的数据删除掉

删:remove()将当前获取的元素删除掉。

注意:1)删除的是next()取出的元素。且只能删除一次!

2)调用1次next()后只能调用一次remove()!

第二篇:达内学习心得:精心总结的面向对象

达内学习心得:精心总结的面向对象

参赛学员:方钱有 获奖奖项:二等奖 什么面向对象: 个人分析觉得:在程序设计里,面向对象是一种相对说法,相对于面向过程而言的; 面向“对象“:即重点在于“对象”;而面向过程:则重点在于“过程”,简单说:就是我我们看待事物在眼光上注重点不一样;比如说:我们评判一个女孩漂亮与否,有的人看重外表,有的人则看重“心灵”,只是侧重点不一样。举个例子:把大象装进冰箱!

面向过程

面向对象

(注重一系列动作即过程)

(注重动作所操作的承受者[“对象”])

“打开”冰箱

“冰箱”打开

“装入”大象

“大象”装入

“关闭”冰箱

“冰箱”关闭

类:通俗的说类就是“一类事物的简称”,并且这些事物至少具有一点“共同的”特征.比如说:动物就是一个类

对象:就是某一类中一个具体的(就是可以具体描述出来的)东西,比如:动物(类)里的“狗”就是一个对象。(个人觉得对象相对于类而言的,因为狗又可以分好多种,‘狗’相对于‘哈士奇’是一个类,‘哈士奇’是‘狗’类的一个具体对象)

在生活中就拿描述汽车来说,我们都知道汽车都有4个轮子; 都有跑的功能 可以如下描述:

汽车

属性: 4个轮

功能: 跑

那么怎么在Java中描述汽车这类呢? class car{

int wheel=4;//属性: 4个轮

void run(){//方法(功能): 跑

System.out.println(“是汽车都会跑”);

} } 那么可见“出租车”应当是“汽车”这类的一个具体化(实实在在的例子即“实例”)对象,那自然出租车也就具备了汽车这类所具备的“共有”属性功能!

如何创建一个出租车对象呢?java中通过new关键字来创建一个类的实例即对象,也叫类的实例化,就是把类具体化成一个实例嘛!格式:类名

对象名 = mew 类名

()

Car

texi =

new Car();创建了“出租车”对象(实例)之后那么它也就有了如下“自己”的属性和功能。

int wheel=4;//属性: 4个轮

void run(){//功能: 跑

System.out.println(“我是出租车我也会跑”);

} 我们如何来访问对象中的它自己的属性和方法呢? 格式:对象.属性;

对象.方法名();

这一点也验证了面向对象编程的侧重点在于“对象”上;

texi.wheel;

texi.run()*********************************************************************************************************************************************************************************************************************************************

1.封装:

从字面可以解读为将东西封起来再装好。要想拿到里面的东西就得有相应的方法打开,才能拿到。

举例来说:一个房间的门如果没有上锁,那么大家都可以进去拿东西,但现在我们不想让谁都进来拿东西,我们可以将房门上锁,只对外提供一把钥匙,只有有钥匙的人才能进来,这就是“封装”现象!

在java程序中,“封装”现象如何实现呢?

可以这样实现:将类中的一些属性和方法用private关键字修饰,将他们“私有化(即不对外直接公开)”,使外部其他类不能通过创建该类对象或通过类名直接访问这些属性和方法;只对外提供公有的方法,外部其他类必须通过该类对外提供的公有方法来访问该类的相应成员;例如: class Person{

private String name;//将name属性私有化(封装)[相当于了上锁]使外部其他类不能直接访问到

public SetName(String name){//对外提供公有方法(相当于房门钥匙)供外部其他类访问到本类属性

this.name=name;

} }

2.继承:

从字面来说继承就是子父类关系的简称,就是儿子(女儿也行,好吧)会继承老爸的一些属性和行为

在java中如何描述继承关系呢?

注意:

第一得知道在java中继承是类与类之间或者是接口与接口之间才有继承关系;通过extends关键字来描述继承关系 例如:老爸这个类 class Dad{

String sex=man;

void smoke(){

System.out.println(“老子会抽烟!”);

} } 那么我们怎么来让儿子这个类继承老爸这个类呢?

class Son extends Dad{//通过extends关键字儿子这个类就继承老爸这个类了

String name;//定义自己的属性

String sex=man;//继承过来的属性,无须再定义,这里写出来是为了好理解

void smoke(){//继承过来的方法,无须再定义,这里写出来是为了好理解

System.out.println(“老子会抽烟!”);

}

void playBall(){//定义自己的方法

System.out.println(“儿子即会打球又会抽烟!”);

}

void somke(){//重写的方法

System.out.println(“我不抽20块以下的烟”);

}

void smoke(int n){//重载的方法

System.out.println(“我抽了+n+”年的烟了“);

} } 那么具有继承关系的两个类有什么特点呢?

1)子类会将父类的属性和方法继承过来,当然子类也可以自己定义的属性和方法 2)当子类自己定义的方法和父类继承过来的方法相同时会发生“重写“现象!3)父类用private关键字私有的方法是不能被继承的!4)子类可以使用super访问父类的属性和方法 5)子类通过重写父类方法,修改父类的功能 6)子类构造器一定调用父类的无参构造器 7)构造器不能继承

3.多态:

字面意思就是多种形态,也就是说一种事物同时局部多种形态.注意:要出现多态情况,那么类和类之间一定得是继承关系,或者类和接口是实现关系 我觉得:在java中多态是相对于一个对象而言的,就是父类型引用变量引用子类对象,并且父类型引用变量可以接受不同子类的对象 例如:拿上面的举例

Dad uncle=new Son();父类引用变量uncle即具备Son类的成员又具备父类的成员;这也称为“向上造型”; 多态时的特点

1)多态时访问成员变量,如uncle.name;编译时看等号左边,父类有该成员变量则编译通过,否则编译出错!运行时也看等号左边,有则运行结果 2)多态时访问方法,如uncle.smoke()编译时看等号左边,父类有该成员方法则编译通过,否则编译出错!运行时看等号右边,父类有该方法,子类没有该方法执行父类方法;父类有该方法,子类也有该方法执行子类方法 3)多态时访问静态方法 编译运行都看等号左边

******************************************************************************************************************************************************************************************************************************************************************

4.抽象(有争议):

什么是抽象?

抽象就是不具体。

一般我们把不能具体描述的东西约定俗成为“抽象”的东西。例如:我们说一个人长得很“抽象”,n你想你能具体形容描述出来么? 在JAVA中如何描述抽象这个概念呢?

我觉得在java中抽象类是由抽象方法而衍生出来的,为什么呢?

因为Java规定一个类中定义了抽象方法那这个类就跟着必须定义为抽象类,而不是因为先定义抽象类再跟着规定抽象类中的方法必须是抽象的,可能最后理解的结果是一样的但性质是不一样的(个人理解)简单说:就是有抽象方法的类一定是抽象类,但是抽象类中不一定都是抽象方法,也可以有具体方法。首先就是当我要在一个类定义一个方法时,暂时我不知道该方法具体功能是什么;等我想好了我在用他实现一个功能时我再具体描述他功能,这样我们就可以将这个方法用abstract关键字修饰定义为抽象方法

(还有一点也就是什么时候定义抽象类的?也可以说抽象类是向上抽取而来的,就是几个类据有共同的属性和方法,不想每个类都定义一次,那么定义一个公有类(即抽象类)其他类只要继承抽象类再重写方法就行!)

例如:我有一百块钱,现在我不知道怎么用,等我想好了在具体怎么用!abstract class Money{//因为有了抽象方法所以必须定义为抽象类

public abstract void buySomthing();//现在不知道怎么用,那就把它的功能代码体去掉 } //现在我饿了,想买东西吃了,我就知道怎么用了 class Hungry extends Money{

void buySomething(){

System.out.println(”我饿了,现在我要买东西吃!“)

} } 抽象类的特点

1)抽象类不能实例化 2)抽象类可以继承抽象类

3)继承抽象类必须得重写抽象方法

5.抽象类,接口,普通类 的不同点和相同点?

1)不同点:

普通类

接口

抽象类 可以直接实例化对象

不可以直接实例化对象

不可以直接实例化对象

可以定义任何成员

只能定义抽象成员方法和常量

成员方法必须定义为抽象其他和普通类相同

可以被继承

类可以实现接口,且可以实现多个接口

可以被继承

接口可以继承多个接口

抽象类有构造方法,接口中不能有

抽象类有普通成员变量,接口中没有

抽象类可以有非抽象方法,接口中不能有

抽象类可以用public、protected修饰,接口中只能public(默认public)

抽象类包含静态方法,接口中没有

接口中的变量只能是public static final,抽象类中可以是任意类型修饰

2)相同点:都可以用于描述(封装)事物的,内部类分为哪几种?分别如何创建对象? 分为 局部内部类,匿名内部类...3种

1)外部类名.内部类名 对象名=new 外部类名().new 内部类名()2)外部类名.内部类名 对象名=外部类名.new 内部类名()3)....不记得了第3种 匿名内部类

二、集合集合的定义?

集合:用来保存一组数据的数据结构

集合的父接口,实现接口,实现类,实现类的常用方法是什么?(建议以树状图画出来,便于加深印象)。

Collection

list

set

Arraylist

LinkedList

HashSet TreeSet

1.List集合

List集合的特征是元素可重复且有序 ;我们可以把他看成是一个动态数组,一般通过下标访问

ArrayList和LinkedList最常用的两个子类实现 1)list可以使用for循环遍历 for(int i=;i

list.get(i);} 2)list的浅层复制

调用ArraryList.clone()方法

注意:不能使用list.clone(),clone()方法是Object类的方法,list是接口是不能继承Object类的

2.Set集合: 不重复且无序集

遍历set只能迭代器,用迭代器遍历集合遵循的操作原则:先问后取。问一次取一次。Iterator it=set.iterator();while(it.hashnext()){

E e=it.next();} 3)map表

Map存储数据使用key-value(键-值)对的形式存储数据的。

对于Map而言,要求key值是唯一的。value值可以重复

获取数据时,使用key可以获取其对应的value 遍历map有3种方法 1)遍历key

Set keySet = map.keySet();

for(String key:keySet){

System.out.println(”key:“ + key);

//可以根据每一个key获取其对应的value值

int value = map.get(key);2)遍历value Collection values = map.values();

Iterator it = values.iterator();

while(it.hasNext()){

int value = it.next();//不能采用 map.next()

System.out.println(”value:“ + value);注意:通过迭代器在遍历集合的过程中,不能通过集合(即不能采用 map.next())去改变集合元素数量

3)遍历键值对

Set> entries= map.entrySet();

for(Entry entry : entries){

//获取一组键值对的键和值

String key = entry.getKey();

int value = entry.getValue();

System.out.println(key + ”=" + value);

Collection接口方法的定义

这里我主要列举 Iterator iterator()方法的使用

Collection提供的方法 Iterator iterator()方法来获取迭代器 Iterator是一个接口,定义了遍历集合应有的方法。

使用迭代器遍历集合遵循的操作原则:先问后取。问一次取一次。

问:boolean hashNext()

取:Object next()

迭代器可以将取出的数据删除掉

删:remove()将当前获取的元素删除掉。

注意:1)删除的是next()取出的元素。且只能删除一次!

2)调用1次next()后只能调用一次remove()!

第三篇:学习心得《面向对象》

面向对象课程学习心得

这学期的面向对象课程对我来说是收获匪浅的一门课。通过老师课件的讲解,自己一些相关书籍的阅读和实践作业的完成,逐步对课程有了由浅及深的认识。

面向对象(Object Oriented,OO)是一门以实践为主课程,课程中可以分开两块OOA(面向对象系统分析)和OOD(面向对象系统设计)。OOA(面向对象系统分析)主要内容: 研究问题域和用户需求,运用面向对象的观点和原则发现问题域中与系统责任有关的对象,以及对象的特征和相互关系.OOA不涉及针对具体实现采取的设计决策和有关细节,独立于具体实现的系统模型。是一个完整确切反映问题域和用户需求的系统模型。OOA的优势:复用、可扩展、可维护性、弹性。

OOD(面向对象系统设计):以OOA模型为基础,按照实现的要求进行设计决策,包括全局性的决策和局部细节的设计,与具体的实现条件相关。OOD的步骤:细化重组类→细化和实现类之间的关系,明确其可见性→增加属性,指定属性的类型和可见性→分配职责,定义执行每个职责的方法→对消息驱动的系统,明确消息传递的方式→利用设计模式进行局部设计→画出详细的类图和时序图。

面向对象的分析与设计方法将致力于解决传统软件研发过程中由于软件模块化结构化程度不高带来的软件重用性差、软件可维护性差、开发出的软件不能满足用户需要等方面问题。面向对象的概念包括:对象、对象的状态和行为、类、类的结构、消息和方法。对象概念将包含对象唯一性、抽象性、继承性、多态性的重要特征。面向对象的要素包含:抽象、封装性、共享性三方面。

在设计模式的研究过程中,我们组选择的是迭代器(Iterator)的设计模式研究。完成设计研究后,我对迭代器的设计模式有了更为深刻的理解。迭代器(Iterator)提供一个方法顺序访问一个聚合对象的各个元素,而又不暴露该对象的内部表示。并了解到迭代器设计模式一般在以下三类场合使用较多。

 访问一个聚合对象的内容而无需暴露它的内部表示。 支持对聚合对象的多种遍历。因为遍历状态是保存在每一个迭代器对象中的。

 为遍历不同的聚合结构提供一个统一的接口。根据实现方式的不同,效果上会有差别。同时还简化了容器的接口。但是在java Collection中为了提高可扩展性,容器还是提供了遍历的接口。在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据。面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责。Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。

在Java Collection的应用中,提供的具体迭代器角色是定义在容器角色中的内部类。这样便保护了容器的封装。但是同时容器也提供了遍历算法接口,你可以扩展自己的迭代器。至于迭代器模式的使用。客户程序要先得到具体容器角色,然后再通过具体容器角色得到具体迭代器角色。这样便可以使用具体迭代器角色来遍历容器了。

OOA和OOD之间没有明显的界限。OOA与OOD的不可分割性正好说明了OO思想的强大,即软件过程阶段的无缝连接,在交流与沟通中不会产生鸿沟,这是相对结构化思想的好处,因为从功能模块到某块详细控制逻辑设计两者之间的联系不是十分紧密,需要分析人员与设计人员的再沟通。

通过课程的学习与实践,对面向对象的理念,以及相关方法,设计模式有了更为深刻的理解与掌握。针对面向对象的分析与设计课程的授课内容及方法,我个人觉得对我还是有不少的帮助和 提高。结合自己的工作,虽然与开发接触的比较少,但是在运维过程中,如果能了解开发原理,结合实际的工作,会对一些源代码的分析能力以及工作效率的提高起到明显的帮助作用。

第四篇:C#面向对象学习心得

一、封装

这是一种隐藏信息的特性。拿本节引例来说,类CalculateDate 将数据结构与算法隐藏在类的内部,外界使用者无需知道具体技术实现细节即可使用此类。封装这一特性不仅大大提高了代码的易用性,而且还使得类的开发者可以方便地更换新的算法,这种变化不会影响使用类的外部代码。可以用以下公式展示类的封装特性:封装的类=数据+对此数据所进行的操作(即算法)。通俗地说,封装就是:包起外界不必需要知道的东西,只向外界展露可供展示的东西。在面向对象理论中,封装这个概念拥有更为宽广的含义。小到一个简单的数据结构,大到一个完整的软件子系统,静态的如某软件系统要收集数据信息项,动态的如某个工作处理流程,都可以封装到一个类中。具备这种“封装”的意识,是掌握面向对象分析与设计技巧的关键。

二、继承

继承是面向对象编程中一个非常重要的特性,它也是另一个重要特性——多态的基础。现实生活中的事物都归属于一定的类别。在一些书中,将父类称为超类(super class)。“继承”关系有时又称为“派生”关系,“B 继承自A”,可以说为“B 派生自A”,或反过来说,“A 派生出B”。父类与子类之间拥有以下两个基本特性:

(1)是一种(IS-A)关系:子类是父类的一种特例。

(2)扩充(Extends)关系:子类拥有父类所没有的功能。

1.类成员的访问权限

面向对象编程的一大特点就是可以控制类成员的可访问性。当前主流的面向对象语言都拥有以下三种基本的可访问性:

(1)公有 public 访问不受限制。

(2)私有 private 只有类自身成员可以访问。

(3)保护 protected 子类可以访问,其他类无法访问。

由此可见,可以通过子类对象访问其父类的所有公有成员,事实上,外界根本分不清楚对象的哪些公有成员来自父类,哪些公有成员来自子类自身。小结一下继承条件下的类成员访问权限:

(1)所有不必让外人知道的东西都是私有的。

(2)所有需要向外提供的服务都是公有的。

(3)所有的“祖传绝招”,“秘不外传”的都是保护的。

C#中还有一种可访问性,就是由关键字internal 所确定的“内部”访问性。internal 有点像public,外界类也可以直接访问声明为internal 的类或类的成员,但这只局限于同一个程序集内部。

读者可以简单地将程序集理解为一个独立的DLL 或EXE 文件。一个DLL 或EXE 文件中可以有多个类,如果某个类可被同一程序集中的类访问,但其他程序集中的类不能访问它,则称此类具有internal 访问性。internal 是C#的默认可访问性,这就是说,如果某个类没有任何可访问性关键字在它前面,则它就是internal 的。

2.子类父类变量的相互赋值

子类对象可以被当成基类对象使用。这是因为子类对象本就是一种(IS_A)父类对象,因此,以下代码是合法的:

Parent p;

Son c = new Son();

p = c;

然而,反过来就不可以,父类对象变量不可以直接赋值给子类变量。如果确信父类变量中所引用的对象的确是子类类型,则可以通过类型强制转换进行赋值,其语法格式为: 子类对象变量=(子类名称)基类对象变量;

子类对象变量=基类对象变量 as 子类名称;

3.方法重载、隐藏与虚方法调用

由于子类对象同时汇集了父类和子类的所有公共方法,而C#并未对子类和父类的方法名称进行过多限制,因此,一个问题出现了:如果子类中某个方法与父类方法的签名一样(即方法名和方法参数都一样),那当通过子类对象访问此方法时,访问的是子类还是父类所定义的方法?让我们先从子类方法与父类方法之间的关系说起。总的来说,子类方法与父类方法之间的关系可以概括为以下三种:

(1)扩充(Extend):子类方法,父类没有;

(2)重载(Overload):子类有父类的同名函数,但参数类型或数目不一样;

(3)完全相同:子类方法与父类方法从方法名称到参数类型完全一样。

当子类与父类拥有完全一样的方法时,称“子类隐藏了父类的同名方法,当分别位于父类和子类的两个方法完全一样时,调用哪个方法由对象变量的类型决定。“new”关键字明确告诉C#编译器,子类隐藏父类的同名方法,提供自己的新版本。如果子类隐藏了父类的同名方法,要在子类方法的实现代码中调用父类被隐藏的同名方法时要使用base 关键字。如果子类隐藏了父类的同名方法,不进行强制转换,就无法通过父类变量直接调用子类的同名方法,哪怕父类变量引用的是子类对象。这是不太合理的。我们希望每个对象都只干自己职责之内的事,即如果父类变量引用的是子类对象,则调用的就是子类定义的方法,而如果父类变量引用的就是父类对象,则调用的是父类定义的方法。这就是说,希望每个对象都“各人自扫门前雪,莫管他人瓦上霜”。为达到这个目的,可以在父类同名方法前加关键字virtual,表明这是一个虚方法,子类可以重写此方法:即在子类同名方法前加关键字override,表明对父类同名方法进行了重写。所以,将父类方法定义为虚方法,子类重写同名方法之后,通过父类变量调用此方法,到底是调用父类还是子类的,由父类变量引用的真实对象类型决定,而与父类变量无关!很明显,“虚方法调用”特性可以让我们写出非常灵活的代码,大大减少由于系统功能

扩充和改变所带来的大量代码修改工作量。由此给出结论:面向对象语言拥有的“虚方法调用”特性,使我们可以只用同样的一个语句,在运行时根据对象类型而执行不同的操作。

三、抽象

1.抽象类与抽象方法

在一个类前面加上“abstract”关键字,此类就成为了抽象类。对应地,一个方法类前面加上“abstract”关键字,此方法就成为了抽象方法。注意抽象方法不能有实现代码,在函数名后直接跟一个分号。抽象类专用于派生出子类,子类必须实现抽象类所声明的抽象方法,否则,子类仍是抽象类。抽象类一般用于表达一种比较抽象的事物,而抽象方法则说明此抽象类应该具有的某种性质,从同一抽象类中继承的子类拥有相同的方法(即抽象类所定义的抽象方法),但这些方法的具体代码每个类都可以不一样。抽象类不能创建对象,一般用

它来引用子类对象。一个抽象类中可以包含非抽象的方法和字段。因此:包含抽象方法的类一定是抽象类,但抽象类中的方法不一定是抽象方法。除了方法可以是抽象的之外,属性也可以是抽象的。

2.接口

接口可以看成是一种“纯”的抽象类,它的所有方法都是抽象方法。抽象类定义了对象所属的类别,而接口实际上定义了一种对象应具有的行为特性。某个类可以实现多个接口,当创建一个此类的对象之后,通过引用这个对象的对象变量可以访问其所有的公有方法(包括自身的公有方法以及由接口定义的公有方法以)。在这种情况下,根本分不清哪些方法是由接口定义的,哪些是由类自己定义的。C#提供了一种“显式接口”实现机制,可以区分开这两种情况。由此得到一个结论:如果一个类显式实现某个接口,则只能以此接口类型的变量为媒介调用此接口所定义的方法,而不允许通过类的对象变量直接调用。或者这样说:被显式实现的接口方法只能通过接口实例访问,而不能通过类实例直接访问。

四、多态

方法重载属于多态的一种,两个构成重载关系的函数必须满足几个条件:函数名相同、参数类型不同,或参数个数不同。具体调用哪个方法要看参数,需要注意的是,方法返回值类型的不同不是方法重载的判断条件。多态编程的基本原理是:使用基类或接口变量编程。在多态编程中,基类一般都是抽象基类,其中拥有一个或多个抽象方法,各个子类可以根据需要重写这些方法。或者使用接口,每个接口都规定了一个或多个抽象方法,实现接口的类根据需要实现这些方法。因此,多态的实现分为两大基本类别:继承多态和接口多态。

1.接口多态与继承多态

接口多态与继承多态其编程方式与作用都是类似的。但由于一个类可以实现多个接口,所以,接口多态较继承多态更灵活,因而在编程中也用得更广。多态是面向对象技术中最精华的部分之一。大量的精巧软件设计方案都建立在对多态特性的巧妙应用上。在编程中应用多态,可以将其简化为两句:应用继承实现对象的统一管理;应用接口定义对象的行为特性。对比传统的不使用多态的编程方式,使用多态的好处是:当要修改程序并扩充系统时,需要修改的地方较少,对其他部分代码的影响较小。

五、类与对象

类是面向对象编程的基本单元,与使用C语言等结构化编程语言不一样,使用C#编程,所有的程序代码几乎都放在类中,不存在独立于类之外的函数。一个类可以包含两种成员:静态成员和实例成员,静态成员是供类的所有对象所共享的,而实例成员只供某一个对象所有。实例成员与静态成员的访问规则:位于同一类中的实例方法可直接相互调用;类的字段(包括实例字段和静态字段)可以被同一类中的所有实例方法直接访问;类中的静态方法只能直接访问类静态字段。

类中包括:方法和字段,属性是一种特殊的字段,它可以保证数据的合法性,方法和字段这两个概念是面向对象理论的术语,是通用于各种面向对象语言的。字段(Field)代表了类中的数据,在类的所有方法之外定义一个变量即定义了一个字段。在变量之前可以加上public、private 和protected 表示字段的访问权限。方法(function)功能代码的集合,在程序开发过程中,经常发现多处需要实现或调用某一个公用功能,这些功能的实现都需要书

写若干行代码。如果在调用此功能的地方重复书写这些功能代码,将会使整个程序中代码大量重复,会增大开发工作量,增加代码维护的难度。为了解决代码重复的问题,绝大多数程序设计语言都将完成某一公用功能的多个语句组合在一起,起一个名字用于代表这些语句的全体,这样的代码块被称为“函数(function)”。引入“函数”概念之后,程序中凡需要调用此公用功能的地方都可以只写出函数名,此名字就代表了函数中所包含的所有代码,这样一来,就不再需要在多个地方重复书写这些功能代码。

对象是以类为模板创建出来的。类与对象之间是一对多的关系。在C#中,使用new 关键字创建对象。在程序中“活跃”的是对象而不是类。在面向对象领域,对象有时又被称为是“类的实例”,“对象”与“类的实例”这两个概念是等同的。

六、值类型与引用类型

1.值类型

值类型变量与引用类型变量的内存分配模型也不一样。每个正在运行的程序都对应着一个进程(process),在一个进程内部,可以有一个或多个线程(thread),每个线程都拥有一块“自留地”,称为“线程堆栈”,大小为1M,用于保存自身的一些数据,比如函数中定义的局部变量、函数调用时传送的参数值等,这部分内存区域的分配与回收不需要程序员干涉。所有值类型的变量都是在线程堆栈中分配的。值类型共有三种:简单类型、枚举类型和结构类型。

2.引用类型

另一块内存区域称为“堆(heap)”,在.NET 这种托管环境下,堆由CLR 进行管理,所以又称为“托管堆(managed heap)”。用new 关键字创建的类的对象时,分配给对象的内存单元就位于托管堆中。在程序中我们可以随意地使用new 关键字创建多个对象,因此,托管堆中的内存资源是可以动态申请并使用的,当然用完了必须归还。打个比方更易理解:托管堆相当于一个旅馆,其中的房间相当于托管堆中所拥有的内存单元。当程序员用new 方法创建对象时,相当于游客向旅馆预订房间,旅馆管理员会先看一下有没有合适的空房间,有的话,就可以将此房间提供给游客住宿。当游客旅途结束,要办理退房手续,房间又可以为其他旅客提供服务了。引用类型共有四种:类类型、接口类型、数组类型和委托类型。所有引用类型变量所引用的对象,其内存都是在托管堆中分配的。严格地说,我们常说的“对象变量”其实是类类型的引用变量。但在实际中人们经常将引用类型的变量简称为“对象变量”,用它来指代所有四种类型的引用变量。

七、命名空间与类库

1.命名空间

在使用面向对象技术开发的现代软件系统中,经常拥有数百甚至上千个类,为了方便地管理这些类,面向对象技术引入了“命名空间(namespace)”的概念。命名空间可以看成是类的“容器”,它可以包含多个类。.NET Framework 使用命名空间来管理所有的类。如果把类比喻成书的话,则命名空间类似于放书的书架,书放在书架上,类放在命名空间里。当我们去图书馆查找一本书时,需要指定这本书的编号,编号往往规定了书放在哪个书库的哪个书架上,通过逐渐缩小的范围:图书馆->书库->书架,最终可以在某个书架中找到这本书。类似地,可以采用图书馆保存图书类似的方法来管理类,通过逐渐缩小的范围:最大的命名空间->子命名空间->孙命名空间„„,最终找到一个类。

2.类库

为了提高软件开发的效率,人们在整个软件开发过程中大量应用了软件工程的模块化原则,将可以在多个项目中使用的代码封装为可重用的软件模块,其于这些可复用的软件模块,再开发新项目就成为“重用已有模块,再开发部分新模块,最后将新旧模块组装起来”的过程。整个软件开发过程类似于现代工业的生产流水线,生产线上的每个环节都由特定的人员负责,整个生产线上的工作人员既分工明确又相互合作,大大地提高了生产效率。在组件化开发大行其道的今天,人们通常将可以重用的软件模块称为“软件组件”。在全面向对象的.NET 软件平台之上,软件组件的表现形式为程序集(Assembly),可以通过在Visual Studio 中创建并编译一个类库项目得到一个程序集。在Visual Studio 的项目模板中,可以很方便地创建类库(Class Library)项目,Visual Studio 会自动在项目中添加一个名为Class1.cs 的类文件,程序员可在此类文件中书写代码,或者添加新的类。一个类库项目中可以容纳的类数目没有限制,但只有声明为public 的类可以被外界使用。类库项目编译之后,会生成一个动态链接库(DLL:Dynamic Link Library)文件。这就是可以被重用的.NET 软件组件——程序集。默认情况下,类库文件名就是项目名加上“.dll”后缀。每个类库项目都拥有一个默认的命名空间,可以通过类库项目的属性窗口来指定。需要仔细区分“类库项目”、“程序集”和“命名空间”这三个概念的区别:

(1)每个类库项目编译之后,将会生成一个程序集。

(2)类库项目中可以拥有多个类,这些类可属于不同的命名空间。

(3)不同的类库项目可以定义相同的命名空间。

根据上述三个特性,可以得到以下结论:“命名空间”是一个逻辑上的概念,它的物理载体是“程序集”,具体体现为“DLL”(或EXE)文件。在Visual Studio 中,可通过创建“类库”类型的项目生成程序集。一个程序集可以有多个命名空间,而一个命名空间也可以分布于多个程序集。一旦生成了一个程序集,在其他项目中就可以通过添加对这一程序集的引用而使用此程序集中的类。其方法是在“项目”菜单中选择“添加程序集”命令,激活“浏览”卡片,选择一个现有的程序集文件(DLL 或EXE)。一个项目添加完对特定程序集的引用之后,就可以直接创建此程序集中的类了,当然要注意指明其命名空间。

八、委托

委托是一种新的面向对象语言特性,在历史比较长的面向对象语言比如C++中并未出现过。微软公司在设计运行于.NET Framework平台之上的面向对象语言(如C#和VisualBasic.NET)时引入了这一新特性。委托(delegate)也可以看成是一种数据类型,可以用于定义变量。但它是一种特殊的数据类型,它所定义的变量能接收的数值只能是一个函数,更确切地说,委托类型的变量可以接收一个函数的地址,很类似于C++语言的函数指针。简单地说:委托变量可看成是一种类型安全的函数指针,它只能接收符合其要求的函数地址。委托可以看成是一个函数的“容器”,将某一具体的函数“装入”后,就可以把它当成函数一样使用。定义委托类型时对函数的要求被称为函数的“签名(signature)”。函数的签名规定了函数的参数数目和类型,以及函数的返回值,体现了函数的本质特征。每一个委托都确定了一个函数的签名。拥有不同签名的函数不能赋值给同一类型的委托变量。因此,一个委托类型的变量,可以引用任何一个满足其要求的函数。

1.委托的组合与分解

委托变量可以代表某一函数,使用委托变量就相当于调用一个函数。如果仅是这么简单,那么直接调用函数不就行了吗?为什么还要引入“委托”这一特性?事实上,委托不仅可以代表一个函数,还可以组合“一堆”的函数,然后批量执行它们,这样的委托变量又称为“多路委托变量”。可以用加法运算符来组合单个委托变量为多路委托变量。类似地,也可以使用减法运算符来从一个多路委托变量中移除某个委托变量。

2.事件与多路委托

事件的主要特点是一对多关联,即一个事件源,多个响应者。在具体技术上,.NET Framework 的事件处理机制是基于多路委托实现的。事件与多路委托其实大同小异,只不过多路委托允许在事件源对象之外激发事件罢了。所有的.NET Framework 可视化窗体控件的预定义事件,都是某一对应的“事件名+Handler”委托类型的变量。与此事件相关的信息都封装在“事件名+Args”类型的事件参数中,此事件参数有一个基类EventArgs,它是所有事件参数的基类。明了上述内部机理,对于我们在程序中定义自己的事件非常有好处,尤其是开发一个自定义的可视化控件时,如果需要增加新的事件类型,我们应尽量遵循.NET Framework 的定义事件的框架,给事件取一个名字,定义一个“事件名+Handler”的事件委托类型,再从EventArgs 派生出自定义事件的参数,取名为“事件名+Args”。

面向对象的软件系统有许多都是事件驱动的,ASP.NET 就采用了“事件驱动”的编程方式。所谓“事件驱动”的开发方式,就是指整个系统包含许多的对象,这些对象可以引发多种事件,软件工程师的主要开发工作就是针对特定的事件书写代码响应它们。.NET 事件处理机制建立在委托的基础之上,而这两者都是ASP.NET 技术的基础之一。因此,必须牢固地掌握好委托和事件这两种编程技术,才能为掌握ASP.NET 技术扫清障碍。

第五篇:java面向对象的学习心得

Java面向对象的学习心得

大三的时候学校组织我们去苏州NIIT参加四个月的java实训,我开始系统的学习期java,之前大学的时候学的比较宽泛,没有专门的正对java的学习。

首先我是从学习Java编程开始接触OOP(面向对象编程),刚开始使用Java编写程序的时候感觉很别扭,因为我早以习惯用C来编写程序,很欣赏C的简洁性和高效性,喜欢C简练而表达能力丰富的风格,特别忍受不了Java运行起来慢吞吞的速度,相对冗长的代码,而且一个很简单的事情,要写好多类,一个类调用一个类,心里的抵触情绪很强。

我对Java的面向对象的特性琢磨良久,自认为有所领悟,也开始有意识的运用OOP风格来写程序,然而还是经常会觉得不知道应该怎样提炼类,面对一个具体的问题的时候,会觉得脑子里千头万绪的,不知道怎么下手,一不小心,又会回到原来的思路上去。

举个例子,要发广告邮件,广告邮件列表存在数据库里面。倘若用C来写的话,一般会这样思考,先把邮件内容读入,然后连接数据库,循环取邮件地址,调用本机的qmail的sendmail命令发送。

然后考虑用Java来实现,既然是OOP,就不能什么代码都塞到main过程里面,于是就设计了三个类:

一个类是负责读取数据库,取邮件地址,调用qmail的sendmail命令发送; 一个类是读邮件内容,MIME编码成HTML格式的,再加上邮件头;

一个主类负责从命令读参数,处理命令行参数,调用发email的类。

把一件工作按照功能划分为3个模块分别处理,每个类完成一件模块任务。

仔细的分析一下,就会发现这样的设计完全是从程序员实现程序功能的角度来设计的,或者说,设计类的时候,是自低向上的,从机器的角度到现实世界的角度来分析问题的。因此在设计的时候,就已经把程序编程实现的细节都考虑进去了,企图从底层实现程序这样的出发点来达到满足现实世界的软件需求的目标。

这样的分析方法其实是不适用于Java这样面向对象的编程语言,因为,如果改用C语言,封装两个C函数,都会比Java实现起来轻松的多,逻辑上也清楚的多。

我觉得面向对象的精髓在于考虑问题的思路是从现实世界的人类思维习惯出发的,只要领会了这一点,就领会了面向对象的思维方法。

举一个非常简单的例子:假使现在需要写一个网页计数器,客户访问一次页面,网页计数器加1,计数器是这样来访问的后台有一个数据库表,保存每个id(一个id对应一个被统计访问次数的页面)的计数器当前值,请求页面一次,对应id的计数器的字段加1(这里我们忽略并发更新数据库

表,出现的表锁定的问题)。

如果按照一般从程序实现的角度来分析,我们会这样考虑:首先是从HTTP GET请求取到id,然后按照id查数据库表,获得某id对应的访问计数值,然后加1,更新数据库,最后向页面显示访问计数。

现在假设一个没有程序设计经验的人,他会怎样来思考这个问题的呢?他会提出什么样的需求呢?他很可能会这样想:

我需要有一个计数器,这个计数器应该有这样的功能,刷新一次页面,访问量就会加1,另外最好还有一个计数器清0的功能,当然计数器如果有一个可以设为任意值的功能的话,我就可以作弊了。

做为一个没有程序设计经验的人来说,他完全不会想到对数据库应该如何操作,对于HTTP变量该如何传递,他考虑问题的角度就是我有什么需求,我的业务逻辑是什么,软件应该有什么功能。

按照这样的思路(请注意,他的思路其实就是我们平时在生活中习惯的思维方式),我们知道需要有一个计数器类 Counter,有一个必须的和两个可选的方法:

getCount()// 取计数器值方法

resetCounter()// 计数器清0方法

setCount()// 设计数器为相应的值方法

把Counter类完整的定义如下:

public class Counter {

public int getCount(int id){}

public void resetCounter(int id){}

public void setCount(int id, int currentCount){}

}

解决问题的框架已经有了,来看一下如何使用Counter。在count.cgi里面调用Counter来计数,程序片断如下:

// 这里从HTTP环境里面取id值

...Counter myCounter = new Counter();// 获得计数器

int currentCount = myCounter.getCount(id);// 从计数器中取计数

// 这里向客户浏览器输出

...程序的框架全都写好了,剩下的就是实现Counter类方法里面具体的代码了,此时才去考虑具体的程序语言实现的细节,比如,在getCount()方法里面访问数据库,更新计数

值。

从上面的例子中看到,面向对象的思维方法其实就是我们在现实生活中习惯的思维方式,是从人类考虑问题的角度出发,把人类解决问题的思维方式逐步翻译成程序能够理解的思维方式的过程,在这个翻译的过程中,软件也就逐步被设计好了。

在运用面向对象的思维方法进行软件设计的过程中,最容易犯的错误就是开始分析的时候,就想到了程序代码实现的细节,因此封装的类完全是基于程序实现逻辑,而不是基于解决问题的业务逻辑。

学习JDBC编程的经典错误问法是:“我怎样封装对数据库的select操作?”

面向对象的设计是基于解决业务问题的设计,而不是基于具体编程技术的设计。我不会去封装select语句的,我只封装解决问题的业务逻辑,对数据库的读取是在业务逻辑的编码实现阶段才去考虑的问题。

回过头看上面那个发广告邮件的例子,应该如何应用面向对象的思维方法呢?

对于一个邮件来说,有邮件头,邮件体,和邮件地址这三个属性,发送邮件,需要一个发送的方法,另外还需要一个能把所有邮件地址列出来的方法。所以应该如下设计:

类JunkMail

属性:

head

body

address

方法:

sendMail()// 发送邮件

listAllMail()// 列邮件地址

用Java来表示:

public class JunkMail {

private String head;

private String body;

private String address;

public JunkMain(){ // 默认的类构造器

// 从外部配置文件读邮件头和邮件体

this.head=...;

this.body=...;

}

public static boolean sendMail(String address){

// 调用qmail,发送email

}

public static Collection listAllMail(){

// 访问数据库,返回一个邮件地址集合}

}

当把JunkMail设计好了以后,再调用JunkMail类完成邮件的发送,将是非常轻松的事情。

如果说传统的面向过程的编程是符合机器运行指令的流程的话,那么面向对象的思维方法就是符合现实生活中人类解决问题的思维过程。

在面向对象的软件分析和设计的时候,要提醒自己,不要一上来就去想程序代码的实现,应该抛开具体编程语言的束缚,集中精力分析我们要实现的软件的业务逻辑,分析软件的业务流程,思考应该如何去描述和实现软件的业务。毕竟软件只是一个载体,业务才是我们真正要实现的目标。

但是在设计过程中,心里却往往在担心,如果我完全不去考虑程序代码的实现的话,那么我怎么知道我的设计一定合理呢?我怎么知道我设计的类、接口一定可以实现呢?所以经常可以看到的现象就是:

在设计过程中,虽然知道不能过早考虑代码实现,但是每设计一个类,一个接口,心里都要不知不觉的用自己熟悉的编程语言大概的评估一下,看看能否编出来,因此,一不小心,就会又回到按照程序功能实现的思路进行设计的老路上去了。

举个例子来说明,在做Web程序设计的时候,经常要遇到分页显示数据的情况。比如说需要把系统中所有的用户都列出来这样的功能。假设使用User类来表示用户,增加用户addUser(),删除用户deleteUser(),查询所有用户listUsers()方法。而数据库中有一个user表,一条记录是一个用户的信息。下面考虑一下User类的方法的实现:

addUser()和deleteUser()方法都好实现,就是对数据库增加记录和删除记录。对于listUsers()方法,其实就是对user表的select,取出一个记录集。但是该怎么从listUsers()方法中得到所有用户的列表呢?

一个方法调用的返回值只有一个,没有多个,所以很多情况下采用的办法就是返回值定义为集合类型,比如Vector。这样就可以在listUsers()方法的具体代码实现的时候,从数据库依次取出一个个记录,插入到Vector里面来。在主程序里面,调用listUsers()方法可以返回一个Vector,然后再对Vector遍历操作,就可以得到用户列表了。

public class User {

public static void addUser(...){

// 数据库insert一条记录

}

public static void deleteUser(...){

// 数据库delete一条记录

}

public Vector listUsers(...){

// 数据库select结果放到一个集合里面

}

}

这样的设计基本合理,但是仍然有点小问题。因为在设计的时候,就考虑到了用Java的集合类Vector来实现对不定长数据集的存放,因而违反了面向对象设计的一个原则:在设计的时候不应过早的考虑具体程序语言的实现。所以必须用抽象的方法,和具体实现无关的方法来表达业务逻辑。

我们知道,通常对具有集合特征的数据结构进行遍历通常可以使用next和hasNext方法,next实现取下一个用户,hasNext判断是否还有元素。因此我们定义一个接口Iterator,这个接口中定义两个方法next和hasNext:

public interface Iterator {

public boolean hasNext(){}

public Object next(){}

}

而User类的listUses方法返回值改为Iterator接口的实现类:

public class User {

...public Iterator listUsers(){

}

...}

这样就把User类的设计和具体的实现方法分离开了,因为此时任何实现了next()和hasNext()方法的类都可以做为listUsers的返回值,都可以被用来表达“用户列表”,而不仅仅可以使用Vector而已。比如,我可以用ArrayList来表达用户列表,因为ArrayList也实现了Iterator,当然我也可以自己专门写一个类来存放用户列表,只要实现next()和hasNext()方法就行了。

这样在具体的编写代码的时候,程序员具有了最大的灵活性,可以根据具体的情况,采用不同的编程方法来存放用户列表。特别是降低了程序的耦合度,提高了程序的可移植性。对于上面那个JunkMail的listAllMail()方法也同样应该改为接口类型。

然后,在主程序里面就这样来使用User类的listUsers方法:

User myUser = new User();

Iterator iterator = myUser.listUsers();

while(iterator.hasNext()){

iterator.next();

}

这样就可以完全不用考虑程序代码实现了,从高层次上把功能抽象出来,定义成为接口,同时又可以把系统设计的很合理,完全根据业务的需求来进行设计。

结语

通过上面的几个例子的设计说明,使用面向对象的思维方法,其实是一个把业务逻辑从具体的编程技术当中抽象出来的过程,而这个抽象的过程是自上而下的,非常符合人类的思维习惯,也就是先不考虑问题解决的细节,把问题的最主要的方面抽象成为一个简单的框架,集中精力思考如何解决主要矛盾,然后在解决问题的过程中,再把问题的细节分割成一个一个小问题,再专门去解决细节问题。

因而一旦牢牢的抓住了这一点,你就会发现在软件设计和开发过程中,你自己总是会不知不觉的运用面向对象的思维方法来设计和编写程序,并且程序的设计和开发也变得不再那么枯燥,而一个合理运用面向对象技术进行设计和架构的软件,更是具备了思维的艺术美感。

最后,愿面向对象的思维方法也能给您的程序设计之路带来创作的乐趣。

下载达内学习心得:精心总结的面向对象word格式文档
下载达内学习心得:精心总结的面向对象.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    面向对象知识总结

    一、 封装 1.类本身就是一个封装单元 2.实现:A属于私有化;B共有的方法提供给外界访问;C信息隐藏,安全,对外提供清晰的接口 二、继承1.代码共有,方便维护扩展 2.更符合人类遇到的问......

    达内学习心得:俄罗斯方块项目总结

    达内学员:我的俄罗斯方块项目总结 获奖学员:陈启壮 所获奖项:三等奖 内容俄罗斯方块一共三个类中间用等号隔开 软件的开发过程 1 明确业务需求 用自然语言,将业务功能描述清楚......

    达内培训总结

    达内培训总结 今年的7月初我和大多数达内学员一样,兴奋的进入了达内进行培训,开始了C/C++的培训学习,转眼间4个多月已经过了,也结束了我们培训课程。虽然自己学的是软件技术专业,但......

    面向对象编程的总结[五篇范文]

    面向对象编程的总结(理解与看法) 面向对象程序设计 (Object Oriented Programming,OOP,面向对象程序设计)是一种计算机编程架构。OOP 的一条基本原则是计算机程序是由单个能够起到......

    Java面向对象编程习题总结大全

    第一章面向对象开发方法概述 1. 面向对象的软件开发有哪些优点? 1)把软件系统看成是各种对象的集合,这更接近人类的自然思维方式。 2)软件需求的变动性往往是功能的变动,而功......

    达内IT培训学习心得(共5篇)

    在达内为期两周的实习时间已悄然离去,刚来时的那种新鲜好奇早飞到了九霄云外,更多的是离开时的那种不舍和对自己及所学的反思。当我第一天来这里时,和其他同学一样怀着兴奋得......

    达内Java学习心得-第一个月[合集]

    学习心得 七月之始,我们的达内java班又开始正式上课了,从上课第一天到现在,已经有一个月了,在这短暂的一个月里,我学到是java的基础知识,重点是JavaSE。感觉时间过的是非常快的,短......

    《面向对象程序设计》教学大纲

    《面向对象程序设计》教学大纲 课程名称:信息内容安全 课程代码:042504 总 学 时:64 学分:2 课程类型:专业必修课 适用专业: 信息安全专业 制 订 人:徐雪飞 审 定 人:肖文 制订日期......