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也会变成"李"。那么,这个后果是很严重的,因为你可能用到的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点时,停止系统几分钟,改一下配置文件,瞬间项目就改变了。
转载于:https://www.cnblogs.com/zhaowenliang/archive/2013/04/12/3017477.html
6.面向对象的三大基本特征相关推荐
- 什么是面向过程?什么是面向对象?面向对象的三大基本特征是什么?
一.什么是面向过程? 面向过程是一种以过程为中心的编程思想,其原理就是将问题分解成一个一个详细的步骤,然后通过函数实现每一个步骤,并依次调用. 面向过程我们所关心的是解决一个问题的步骤,举个例子,汽车 ...
- 浅谈面向对象的三大基本特征
**类和对象 由类来创建对象,对象调用方法来解决问题 面向对象的三大基本特征: 1,封装:就是一个类里的方法的职能尽量单一,高内聚低耦合 2继承:是由已知类来创建新类的机制.子类继承父类的成员方法但不 ...
- 【Java修行之路】--面向对象的三大基本特征:封装、继承、多态
文章目录 Java面向对象的三大基本特征(封装.继承.多态) 1.Java访问权限修饰符 2.封装 2.1封装问题引例 2.2封装问题实例 2.3私有属性的Setter和Getter方法 2.4方法的 ...
- 面向对象的三大基本特征、五大基本原则
一.三大基本特征 1.封装 封装就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的 ...
- 面向对象的三大基本特征和六大基本原则
面向对象三大特征: (1)封装(Encapsulation) 所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.封装是面向对象的特 ...
- 面向对象的三大基本特征
先说说什么是面向对象? 谈谈你对面向对象的理解 面向对象是一种编程思想.聊到面向对象,我们需要聊一下面向过程的编程方式,因为面向对象是从面向过程过渡而来的. 举个例子: 如果是面向过程的话,我们会将这 ...
- Java面向对象知识详解——三大基本特征
文章目录 前言 什么是面向过程? 什么是面向对象? 三大基本特征 封装 继承 多态 Java中的多态 最后 前言 相信很多程序员在最初接触Java的时候就听过,Java中一切皆对象那么什么是面向对象呢 ...
- 面向对象三大基本特征及五大基本原则介绍
目录 前言 一.面向过程和面向对象区别 二.面向对象的三大基本特征:封装.继承.多态 1.封装 2.继承 3.多态 三.面向对象的五大基本原则 1.单一职责原则(SRP) 2.开放封闭原则(OCP) ...
- 面向对象——三大基本特征
面向对象的三大基本特征:封装.继承和多态 一.封装 利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体.数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些 ...
最新文章
- JSP与Web技术概论
- ​常用的连续概率分布汇总
- linux内核参数优化 for 高并发服务器
- linux上修改ssh密码和mysql密码
- 3.Lasso线性模型
- 在过渡到Agile中的十种错误
- 云端计算机可以玩游戏么,手机掌上云电脑是什么?为什么可以玩PC游戏?
- YolactEdge:首个开源边缘设备上的实时实例分割(Jetson AGX Xavier: 30 FPS)
- linux系统如何创建python文件_Linux搭建python环境详解
- joint和join_MySQL的JOIN(一):用法
- 读书:鲁迅的《故事新编》
- ES6的开发环境搭建 1
- 三星c7 linux驱动,三星c7手机驱动(三星c7驱动程序)V1.5.55.2 专业版
- Clean Code(代码整洁之道)-有意义的命名
- 每日单词20110507
- 搜狗新闻文本分类竞赛
- 新思路,坚持创新;好想法,坚持执行
- BPMS的市场与产品
- 腾讯如何打造一款实时对战手游
- js根据name值获取元素