`
dyllove98
  • 浏览: 1380338 次
  • 性别: Icon_minigender_1
  • 来自: 济南
博客专栏
73a48ce3-d397-3b94-9f5d-49eb2ab017ab
Eclipse Rcp/R...
浏览量:38260
4322ac12-0ba9-3ac3-a3cf-b2f587fdfd3f
项目管理checkList...
浏览量:78488
4fb6ad91-52a6-307a-9e4f-816b4a7ce416
哲理故事与管理之道
浏览量:131645
社区版块
存档分类
最新评论

6.面向对象的三大基本特征

 
阅读更多

封装

有些人可能学Java有半年了,还是搞不懂封装是什么东西。其实我们每天都在用封装。那么封装是什么呢?封装简单来说就是包装。比如说:我们把一堆数据放在一个类里面,并且加上get和set方法,这个就是JavaBean封装。再比如:我们把一些通用的代码放在一个方法里面,以后需要的时候直接调用方法就行了,这就是代码封装。

那么,为什么要用封装呢?封装有什么好处呢?

比如:我们需要一个学生的信息:姓名,年龄。并且在控制台显示出来,我们可以这样写:

public static void main(String[] args){

String name;

int age;

System.out.println("这个学生的名字是:"+name+",年龄是:"+age);

}

那么我想再定义一个学生信息,并且显示呢?我还需要重复这样的代码:重新定义两个变量并赋值。那么再想想,我需要十个学生的信息并且显示呢?还有,实际情况中,一个学生的信息不可能就这么几个变量,可能有十几个呢?难道我每次需要显示学生信息,都要定义这么多变量吗?想想吧,这真是太可怕了。

属性的封装

但是,现在我们可以用封装来实现,怎么实现呢?我们可以把所有的属性放在一个类中,这样,我需要显示学生信息时,只需要实例化一个类就行了。比如:

public class Student{

String name;

int age;

}

我们需要一个学生信息时可以这样写:

Student student=new Student();

student.name="zhangsan";

student.age=12;

System.out.println("name:"+name+",age="+age);

有人可能会说:我怎么感觉除了代码量变大之后没有什么好处啊?是的,单单看这段代码,确实是如此,但是假如我们需要显示一个班级56个学生的信息,而这个班级的所有学生信息的年龄都是相同的,那么我们可以这样定义Student:

public class Student{

String name;

int age=12;

}

那么,实例化一个学生的信息时,我们只需要定义学生姓名就可以了,年龄就默认赋值了,大家现在可以再次对比一个封装和不封装的代码量,你就可以知道哪种更好了。

毫无疑问,从长远角度看以及从更好的适用性来看,通过将数据封装成对象,是很有必要的。

而且,假如你需要显示学生的信息,要显示学生年龄而只知道学生生日时,你需要这样写:

String birthday="2002-01-03";

//截取生日的前四位,获取出生的年份

....

//得到当前的系统时间,从而知道现在是哪一年

....

//通过减法得到年龄

....

//最后定义年龄变量并将计算结果赋值

....

好的,代码就不写了,懂什么意思就行了。那么,大家看这段伪代码,我第一行定义了生日变量,第五行定义了年龄变量,那么请问,假如这个程序有100行,你觉得可能是不是在第80行还可能又出现一个变量?那么,假如你过了很久又看这个程序或者别人看这个程序,他能一眼看出你总共定义了多少跟学生有关的变量吗?毫无疑问,很不方便的,但是,你假如通过封装之后呢?你需要看一下Student类中有多少属性,就马上知道了一个学生有多少变量了。

现在,再看学生Student这个类,假如我在main方法中给一个学生的age属性赋值-1,你说程序会不会出错?当然不会,你又没有规定年龄不能为负数。那么怎么办呢?两步:

一:将属性私有化,这样别人就不能直接访问变量了。

二:将访问变量的方式改为通过方法来访问,可以在方法中增加限制条件

结果如下:

class Student{

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

if(age>0){

this.age = age;

}

}

}

那么请问大家,这样是不是很好呢?要想改年龄赋值,必须调用setAge()方法,那么年龄必须大于0。

代码的封装

代码的封装我就不需要讲了,就是把一段代码封装成一个方法,方便以后的调用。

继承

继承就是子承父业。就是子类可以继承父类的所有属性和方法。有什么用呢?

比如我有一个Father类,姓是"赵",还有一个Son类,姓当然也是"赵"了,那么现在我们按一般的思路,就是建两个类,都有姓这个属性,值都是赵。但是呢?这样我感觉很不爽啊,假如这两个类有十个属性都是一样的,我还需要两个类都这样写吗?太糟糕了。

因此Java产生了继承的概念:

我们可以定义一个Father类,而子类Son继承Father类,这样,姓这个属性就继承过来了,不需要再写一次。

public class Father{

String name="赵";

}

public class Son extends Father{

   

}

虽然Son里面空空的,但是你可以调用Son的name属性。这就是封装的迷人地方。

你可能会说,我可能想改姓呢,怎么办呢?只需要再Son中再定义一次name就好了。

public class Son extends Father{

String name="刘";

}

继承最大的优点就是我们可以重用一个以前写好的类,继续使用原来类中的属性和方法,我们甚至可以修改原来类中某些属性或方法,以符合当前类的需要。

当然,缺点就是假如因为某些原因,你忘了某个类是被继承了,而你又改了这个类的一个属性,那么,它的子类的这个属性都将会改变。比如Father类我name改为"李",而你又不知道这个类被继承了(单看Father类你真不知道这个类被继承了),那么你的所有子类,比如Son类的name也会变成"李"。那么,这个后果是很严重的,因为你可能用到的Sonname应该是赵,不能是李。

多态

多态就是多姿多态。一朵花可以有多种形态:兰花,荷花,水仙花等等。这个世界就是多姿多态的,比如:铅笔有白铅笔,蓝铅笔,花铅笔。鸟有鸡,鸭,鹅等等。那么这些对象之间都有一定 的共性,我们可以运用刚学过的继承概念来写几个类出来。

比如:圆形,方形,三角形都是形状的子类。

//Shape是形状的意思

class Shape{

//形状都有长度

int length;

//形状都有面积

int area;

public int getLength() {

return length;

}

public void setLength(int length) {

this.length = length;

}

public int getArea() {

return area;

}

public void setArea(int area) {

this.area = area;

}

}

class Circle extends Shape{

public int getLength() {

System.out.println("用圆形公式求圆形的长度");

return length;

}

public int getArea() {

System.out.println("用圆形公式求圆形的面积");

return area;

}

}

class Square extends Shape{

public int getLength() {

System.out.println("用方形公式求方形的长度");

return length;

}

public int getArea() {

System.out.println("用方形公式求方形的面积");

return area;

}

}

现在我需要实例化一个圆形和方形,并且求出它们的长度,怎么写呢?

public static void main(String[] args){

Circle circle=new Circle();

Square square=new Square();

circle.getLength();

square.getLength();

}

有人可能会问了,我们想要知道多态的概念,可你讲了半天,怎么都是继承啊!别急,多态来了。

在这里,Java出现了一种新的语法:子类的实例化对象可以被父类的引用表示。代码表示就是:

Shape shape1=new Circle();

为什么这样写呢?好难理解啊。呵呵,这样理解:一个圆形是一个形状对吧?那么,我可以在纸上画一个"圆形",并且说,这是一个"形状"。好,我重复一遍,我指着一个圆说这是一个形状。没问题吧?圆是实际存在的吧?所以我们实例化一下:

new Circle();

我说这是一个形状,这个形状我给它起名字叫shape1:

Shape shape1;

将两边连起来就是:

Shape shape1=new Circle();

现在大家理解了吧?

那么这样有什么好处呢?好处嘛,就是:

Shape shape1=new Circle();

shape1.getLength();

这段代码会得到圆的长度,毕竟我指着的东西是一个圆。

我也可以在这段代码后面加一段:

shape1=new Square();

shape1.getLength();

这段代码又会得到方形的长度,是不是很有趣?

但是它真正的好处并不是这样的,而是:

public staitc void getLenth(Shape shape){

shape.getLength();

}

public static void main(String[] args){

getLength(new Circle());

getLength(new Square());

}

看见了吗?我需要传进去一个Shape子类的实现,就可以调用这个子类的相应的方法,而代码则没有变化,一切都是Java自动帮你完成。

我们甚至可以把Circle这个类以及它的包路径存在一个文件中,比如XML文件中,实例化对象时从文件中取得Circle的信息,通过反射实例化,那么这样就彻底的脱离了具体的实现:

public static void main(String[] args){

//通过文件得到Circle的包路径"com.test.Circle"

Stirng circleStr=getPath();

//通过反射实例化

Shape shape1=Class.forName(circleStr).getInstance();

getLength(shape1);

}

那么这有什么用呢?

1.隐藏了具体的实现代码,你知道调用了getLength方法,但你如果不看文件的内容,你就不知道调用的方法具体内容是什么,因为程序中根本没有体现。

2.傻瓜式代码,我只需要改改文件中的内容,就可以瞬间改变程序的运行结果,即使这个人一点程序基础也没有也可以做到。

3.也就是我们平时开发中为什么经常用到多态的原因:我们需要继续原来的项目运行而又因为客户的需要而改代码时,我们不需要要求客户停止现在的项目,说我们需要改改,等几个月你再运行吧。No,这是在开玩笑,我们可以继承指定的接口,而重写实现类,到时在凌晨3点时,停止系统几分钟,改一下配置文件,瞬间项目就改变了。

分享到:
评论

相关推荐

    最新中农大线上作业Java语言与面向对象程序设计A-F(1).doc

    数据 参考答案:A 您的答案:B 12、面向对象软件开发过程被划分成面向对象分析、面向对象设计和( )三个阶段。 A.Java编程 B.面向对象实现 C.C++编程 D.文档收集 参考答案:B 您的答案:B 13、面向对象分析...

    面向对象程序设计与VC++实践

    第二个层次为第6、7章,介绍Windows编程的基础知识和Windows程序的基本特征,并介绍了应用程序编程接口(API)及其在Windows绘图程序设计中的应用。第三个层次为第8~13章,介绍使用MFC进行Windows应用程序设计的方法,并...

    UML_and_Rose教程.pdf

    1.2 OOA&D 面向对象的基本原则: ............................................. 5 1.3 Rational Rose 的界面介绍............................................... 8 2. 第二周:静态建模:用例和用例图(Use Case ...

    学会这些java面试题让你吊打面试官

    3.面向对象三大特征及详细理解? 4.重载与重写的区别? 5.接口和抽象类区别? 6.实例变量和静态变量的区别? 7.八大基本类型及字节数和位数? 8.switch cach是否支持byte,short和long,是否支持String? 9.String中和Array...

    Java 面试宝典

    22、面向对象的特征有哪些方面 ................................................................................. 16 23、java 中实现多态的机制是什么? ......................................................

    Python 科学计算

    5.1.2 以面向对象方式绘图................142 5.1.3 配置属性...................................143 5.1.4 绘制多个子图 ...........................145 5.1.5 配置文件...................................147 ...

    【05-面向对象(下)】

    •如果希望获得包装类对象中包装的基本类型变量,则可以使用包装类提供的XxxValue()实例方法。 自动装箱与自动拆箱 •JDk还提供了自动装箱和自动拆箱。自动装箱就是把一个基本类型的变量直接赋给对应的...

    SaaS模式下的餐饮管理系统的分析与设计

    3.1.4面向对象系统建模....................................................................................,,16 3.2软件设计模式..................................,,/二0..................,,,.................

    全国计算机二级java题库

    面向对象编程的基本要领和特征。 2. 类的基本组成和使用。 3. 对象的生成、使用和删除。 4. 接口与包。 5. Java类库中常用类和接口。 四、 Java简单数据类型及运算 1. 变量和常量。 2. 基本数据类型及转换。 3. ...

    软件工程-填空题.pdf

    面向对象方法中,继承是指子类继承其父类的全部数据和操作。 9.UML 的定义包括 UML 语义和 UML 表示法两个部分。 10.软件可维护性度量的七个质量特征是可理解性、可测试性、可修改性、可靠性、可移植性、 可使用性和...

    Java复习大纲面试题.doc

    7.面向对象的三大特征是什么? 封装、继承、多态 8.Java实现多态性的机制是什么? 有继承 有方法重写 父类引用指向子类对象 9.什么是方法重载?什么是方法重写?方法重载与方法重写的区别? 方法重载(Overload):是指...

    JavaSE基础学习笔记

    JavaSE 星辰学习笔记 简介 如何高效的学习Java ...面向对象三大特征* 封装概念 代码 封住的意义 继承概念 代码 super注意点 方法的重写 多态 概念 代码 多态注意事项: 有些方法不能重写: instanceof 代码 小结

    Access 2000数据库系统设计(PDF)---001

    33414.3 用“报表向导”创建分组报表 33414.4 使用Access的报表窗口 33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的 控件 34014.6.2 向报表...

    Access 2000数据库系统设计(PDF)---002

    33414.3 用“报表向导”创建分组报表 33414.4 使用Access的报表窗口 33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的 控件 34014.6.2 向报表...

    Access 2000数据库系统设计(PDF)---018

    33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的控件 34014.6.2 向报表添加计算控件 34514.6.3 对齐和格式化控件并调整行间距 34714.7 传统...

    Access 2000数据库系统设计(PDF)---003

    33414.3 用“报表向导”创建分组报表 33414.4 使用Access的报表窗口 33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的 控件 34014.6.2 向报表...

    Access 2000数据库系统设计(PDF)---011

    33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的控件 34014.6.2 向报表添加计算控件 34514.6.3 对齐和格式化控件并调整行间距 34714.7 传统...

Global site tag (gtag.js) - Google Analytics