封装
有些人可能学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也会变成"李"。那么,这个后果是很严重的,因为你可能用到的Son的name应该是赵,不能是李。
多态
多态就是多姿多态。一朵花可以有多种形态:兰花,荷花,水仙花等等。这个世界就是多姿多态的,比如:铅笔有白铅笔,蓝铅笔,花铅笔。鸟有鸡,鸭,鹅等等。那么这些对象之间都有一定 的共性,我们可以运用刚学过的继承概念来写几个类出来。
比如:圆形,方形,三角形都是形状的子类。
//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点时,停止系统几分钟,改一下配置文件,瞬间项目就改变了。
相关推荐
数据 参考答案:A 您的答案:B 12、面向对象软件开发过程被划分成面向对象分析、面向对象设计和( )三个阶段。 A.Java编程 B.面向对象实现 C.C++编程 D.文档收集 参考答案:B 您的答案:B 13、面向对象分析...
第二个层次为第6、7章,介绍Windows编程的基础知识和Windows程序的基本特征,并介绍了应用程序编程接口(API)及其在Windows绘图程序设计中的应用。第三个层次为第8~13章,介绍使用MFC进行Windows应用程序设计的方法,并...
1.2 OOA&D 面向对象的基本原则: ............................................. 5 1.3 Rational Rose 的界面介绍............................................... 8 2. 第二周:静态建模:用例和用例图(Use Case ...
3.面向对象三大特征及详细理解? 4.重载与重写的区别? 5.接口和抽象类区别? 6.实例变量和静态变量的区别? 7.八大基本类型及字节数和位数? 8.switch cach是否支持byte,short和long,是否支持String? 9.String中和Array...
22、面向对象的特征有哪些方面 ................................................................................. 16 23、java 中实现多态的机制是什么? ......................................................
5.1.2 以面向对象方式绘图................142 5.1.3 配置属性...................................143 5.1.4 绘制多个子图 ...........................145 5.1.5 配置文件...................................147 ...
•如果希望获得包装类对象中包装的基本类型变量,则可以使用包装类提供的XxxValue()实例方法。 自动装箱与自动拆箱 •JDk还提供了自动装箱和自动拆箱。自动装箱就是把一个基本类型的变量直接赋给对应的...
3.1.4面向对象系统建模....................................................................................,,16 3.2软件设计模式..................................,,/二0..................,,,.................
面向对象编程的基本要领和特征。 2. 类的基本组成和使用。 3. 对象的生成、使用和删除。 4. 接口与包。 5. Java类库中常用类和接口。 四、 Java简单数据类型及运算 1. 变量和常量。 2. 基本数据类型及转换。 3. ...
面向对象方法中,继承是指子类继承其父类的全部数据和操作。 9.UML 的定义包括 UML 语义和 UML 表示法两个部分。 10.软件可维护性度量的七个质量特征是可理解性、可测试性、可修改性、可靠性、可移植性、 可使用性和...
7.面向对象的三大特征是什么? 封装、继承、多态 8.Java实现多态性的机制是什么? 有继承 有方法重写 父类引用指向子类对象 9.什么是方法重载?什么是方法重写?方法重载与方法重写的区别? 方法重载(Overload):是指...
JavaSE 星辰学习笔记 简介 如何高效的学习Java ...面向对象三大特征* 封装概念 代码 封住的意义 继承概念 代码 super注意点 方法的重写 多态 概念 代码 多态注意事项: 有些方法不能重写: instanceof 代码 小结
33414.3 用“报表向导”创建分组报表 33414.4 使用Access的报表窗口 33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的 控件 34014.6.2 向报表...
33414.3 用“报表向导”创建分组报表 33414.4 使用Access的报表窗口 33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的 控件 34014.6.2 向报表...
33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的控件 34014.6.2 向报表添加计算控件 34514.6.3 对齐和格式化控件并调整行间距 34714.7 传统...
33414.3 用“报表向导”创建分组报表 33414.4 使用Access的报表窗口 33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的 控件 34014.6.2 向报表...
33814.5 使用自动套用格式和自定义报表样式 34014.6 修改基本的“报表向导”报表 34014.6.1 删除、重新部署和编辑现有的控件 34014.6.2 向报表添加计算控件 34514.6.3 对齐和格式化控件并调整行间距 34714.7 传统...