学习 Java 你必须要知道的东西(七)【面向对象】
1. 面向过程 & 面向过程
'面向过程'(Procedure-Oriented Programming,简称POP)是一种计算机编程模型,由一系列要执行的计算步骤组成,通常采用自上而下、顺序执行的方式;步骤简单清晰,第一步做什么,第二步做什么...
'面向对象'(Object-Oriented programming,简写:OOP)是一种计算机编程模型,它围绕数据或对象而不是功能和逻辑来组织软件设计,更专注于对象与对象之间的交互,对象涉及的方法和属性都在对象内部。说的更底层一点就是面向对象是一种依赖于类和对象概念的编程方式;“物以类聚”,是分类的思维模式,首先思考解决该问题需要哪些分类,然后各个分类进行单独思考,最后再对分类下的细节进行 “面向过程” 的思考。
对于描述复杂的事物,为了从宏观上去把握、从整体去合理分析,我们需要使用面向对象的思路来分析整个系统,但是,其实具体到微观操作,依旧是面向过程的思路进行处理。
可以拿生活中的实例来理解面向过程与面向对象,例如五子棋:
面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用不同的方法来实现。
面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。
可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了多个步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。
2. 什么是面向对象
'面向对象编程'(Object Oriented Programming,OOP,面向对象程序设计)的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙一个事物在整个解决问题的步骤中的行为。面向对象程序设计中的概念主要包括:'对象'、'类'、'数据抽象'、'继承'、'动态绑定'、'数据封装'、'多态性'、'消息传递'等,通过这些概念面向对象的思想得到了具体的体现。可以说面向对象编程的本质就是:以类的方式组织代码,以对象的形式组织(封装)数据。
'方法'是指对象能够进行的操作,方法同时还有另外一个名称,叫做函数。方法是类中的定义函数,其具体的作用就是对对象进行描述操作。
'类'是具有相同特性(数据元素)和行为(功能)的对象的抽象。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。类映射的每一个对象都具有这些数据和操作方法,类的继承具有层次性和结构性,高层次对象封装复杂行为,具体细节对该层次知识保持透明,可以减小问题求解的复杂度。
'对象'的含义是指具体的某一个事物,即在现实生活中能够看得见摸得着的事物。在面向对象程序设计中,对象所指的是计算机系统中的某一个成分。在面向对象程序设计中,对象包含两个含义,其中一个是数据,另外一个是动作。对象则是数据和动作的结合体。对象不仅能够进行操作,同时还能够及时记录下操作结果。
'封装'是将数据和代码捆绑到一起,对象的某些数据和代码可以是私有的,不能被外界访问,以此实现对数据和代码不同级别的访问权限。防止了程序相互依赖性而带来的变动影响,面向对象的封装比传统语言的封装更为清晰、更为有力。有效实现了两个目标:对数据和行为的包装和信息隐藏。
'继承'简单地说就是一种层次模型,这种层次模型能够被重用。层次结构的上层具有通用性,但是下层结构则具有特殊性。在继承的过程中类则可以从最顶层的部分继承一些方法和变量。类除了可以继承以外同时还能够进行修改或者添加。通过这样的方式能够有效提高工作效率。在这里举一个例子,当类X继承了类Y后,此时的类X则是一个派生类,而类Y属于一个基类。继承是从一般演绎到特殊的过程,可以减少知识表示的冗余内容,知识库的维护和修正都非常方便。更有利于衍生复杂的系统。
'多态'是指不同事物具有不同表现形式的能力。多态机制使具有不同内部结构的对象可以共享相同的外部接口,通过这种方式减少代码的复杂度。一个接口,多种方式。
'动态绑定'指的是将一个过程调用与相应代码链接起来的行为。动态绑定是指与给定的过程调用相关联的代码只有在运行期才可知的一种绑定,它是多态实现的具体形式。
'消息传递'指对象之间需要相互沟通,沟通的途径就是对象之间收发信息。消息内容包括接收消息的对象的标识,需要调用的函数的标识,以及必要的信息。消息传递的概念使得对现实世界的描述更容易。
关于 “先有对象还是先有类” 这个问题,大致可以理解为:
从认识论角度考虑,是先有对象后有类。对象是具体事物,类是对象的抽象;
从代码运行角度考虑,是先有类后有对象。类是对象的模板。
3. 方法
'方法'是指对象能够进行的操作,方法同时还有另外一个名称,叫做函数。方法是类中的定义函数,其具体的作用就是对对象进行描述操作。
·方法的定义:
修饰符 返回值类型 方法名(参数类型 参数名(形参)...) throws 异常{
方法体...
return 返回值;
}
·return表示结束方法,返回结果
·当方法体中需要抛出异常时,throws异常必须存在,否则可以不写;
·static关键字:
表示静态,与类一起加载。
当static修饰方法时,该方法为静态方法,则 1.该方法可以通过 "类名.方法名" 调用,2.该方法内不可调用非静态方法
tips:非静态方法需要将类实例化后才存在
4. 类和对象
'类'是具有相同特性(数据元素)和行为(功能)的对象的抽象。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。类映射的每一个对象都具有这些数据和操作方法,类的继承具有层次性和结构性,高层次对象封装复杂行为,具体细节对该层次知识保持透明,可以减小问题求解的复杂度。
'对象'的含义是指具体的某一个事物,即在现实生活中能够看得见摸得着的事物。在面向对象程序设计中,对象所指的是计算机系统中的某一个成分。在面向对象程序设计中,对象包含两个含义,其中一个是数据,另外一个是动作。对象则是数据和动作的结合体。对象不仅能够进行操作,同时还能够及时记录下操作结果。
构造方法:
·方法名与类名相同
·无返回值类型,也不能为void
·不手动写构造方法时,默认存在一个空参构造方法
·一旦手动写构造方法,则需要手动写空参构造方法
·new关键字本质上就是调用构造方法
·构造方法的作用是初始化对象的属性值
5. 封装
'封装'是将数据和代码捆绑到一起,对象的某些数据和代码可以是私有的,不能被外界访问,以此实现对数据和代码不同级别的访问权限。防止了程序相互依赖性而带来的变动影响,面向对象的封装比传统语言的封装更为清晰、更为有力。有效实现了两个目标:对数据和行为的包装和信息隐藏。
通常,我们应该禁止直接访问一个对象中数据的实际表示,应该通过操作接口来访问,这即是信息隐藏。
简单来讲,'封装'就是属性私有,使用get/set进行操作
6. 继承
'继承'简单地说就是一种层次模型,这种层次模型能够被重用。层次结构的上层具有通用性,但是下层结构则具有特殊性。在继承的过程中类则可以从最顶层的部分继承一些方法和变量。类除了可以继承以外同时还能够进行修改或者添加,通过这样的方式能够有效提高工作效率。
在这里举一个例子,当类X继承了类Y后,此时的类X则是一个派生类,而类Y属于一个基类。继承是从一般演绎到特殊的过程,可以减少知识表示的冗余内容,知识库的维护和修正都非常方便。更有利于衍生复杂的系统。
关键字:extends
Java中只有单继承,没有多继承;
因为多继承会使设计复杂化,并且会带来各种各样的问题;例如菱形问题:假如A有两个子类B和C,并且进行了方法实现,然后D多继承了B和C,那么D应该继承B的方法还是C的方法?这就是多继承产生的歧义,所以java在设计上就让类不支持多继承。
Java中所有的类默认继承Object类;(祖宗类Object)
继承是类和类之间的一种关系,除此之外还有依赖、组合、聚合等;
super:
1.super 表示该类的父类
2.super(); 表示调用父类的构造方法,使用时必须在第一个(super();和this();不能同时被调用)
3.super 关键字只能出现在子类的方法或构造方法中
4.super 只能在继承条件下使用
重写:
1.需要具有继承关系
2.只有方法体不同,其余必须全部相同
3.修饰符的范围只能扩大, public>protected>default>private;
4.抛出异常范围只能缩小
为什么需要重写?
答:父类的功能,子类不一定需要或不一定满足
Tips:
1.static修饰的方法无法被重写,因为static静态方法跟随类一起加载,只属于本类
2.final修饰的方法无法被重写
3.private方法不可以被重写,或者说不算重写,表示私有,各自属于本类
7. 多态
'多态'是指不同事物具有不同表现形式的能力。多态机制使具有不同内部结构的对象可以共享相同的外部接口,通过这种方式减少代码的复杂度。
注意事项:
1.方法的多态,指的是相同方法的不同表现形式
2.类的多态,类之间必须存在联系
Student s1 = new Student();
Person p1 = new Student();
Object o1 = new Student();
8. instanceof
instanceof 含义:
表示 判断'左边引用'是否为'右边对象'的实例;返回boolean类型结果
格式:
X instanceof Y
Tips:
1. X与Y是否存在父子关系,决定了 是否可以编译通过
2. Object > 父类 > 子类;
父类引用 instanceof 子类对象实例 = true
子类引用 instanceof 父类对象实例 = false
9. 类型转换
基本数据类型转换:
1.长度大的数据类型可以直接转换为长度小的数据类型;
2.长度小的数据类型转换为长度大的数据类型时,需要强制转换,且会丢失精度!!!
引用数据类型转换:
1.子类可以直接转换为父类;
2.父类转换为子类时,需要强制转换;
注意事项:1.父类的引用可以直接指向子类的对象
2.引用数据类型的转换,会得到转换后的数据类型数据,所以该对象的属性和方法,将会由转换后的对象来决定!!!
10. static and final
static 静态修饰符
1.修饰'方法/变量'时,表示 该方法/该变量 是 静态方法/静态变量,在类加载时一起加载,可以通过 '类名.方法名/变量名' 的方式调用;
2.父类子类静态方法,只与本类有关,与本类加载时同时加载;
3.静态代码块,只会在类加载时执行一次且永久存在,多用于赋初始值;
注意事项:
1.静态方法中,不可以调用非静态方法;
2.类加载顺序:静态代码块 > 非静态代码块(匿名代码块) > 构造方法...
final 最终修饰符
1.final修饰的变量称为常量,不可更改;
2.final修饰的方法不可被重写;
3.final修饰类表示该类不可被继承;(断子绝孙)
注意事项:
1.修饰变量为引用数据类型时,地址值无法更改,但是对象属性内容可以改变;
11. 抽象类
abstract 关键字
修饰类时,那么该类就是抽象类;修饰方法时,那么该方法就是抽象方法
抽象类中可以没有抽象方法,但抽象方法必须存在于抽象类中
抽象类不能用new创建对象,它是用来被继承的;抽象方法只能有方法的声明,没有方法的实现,它是用来被子类实现的
当子类继承抽象类时,子类就必须实现抽象类的抽象方法(当子类为抽象类时除外)
Tips:
1.抽象类虽然不能用new创建对象,但是依然存在构造方法,因为抽象类的构造方法在实例化子类之前发生,所以,可以在这个阶段初始化抽象类字段或执行其它与子类相关的代码
2.意义:抽取出来相同的部分,提高开发效率
12. 接口
interface关键字
接口与类完全不同,类为class,接口为interface
接口的作用:
1.制定约束,需要实现类去实现具体的方法内容
2.定义方法,可以被多个实现类去公用实现,分别实现各自的方法内容
3.接口中的方法,默认被public abstract修饰
4.接口中的变量,默认被public static final修饰(常量)
5.接口无法被实例化,因为接口没有构造方法
6.实现接口使用implements关键字,一个实现类可以同时实现多个接口
7.实现类必须实现接口中的全部方法
13. 内部类
定义:内部类就是在一个类的内部再定义的一个类,比如:A类中定义了一个B类,那么B类就是A类的内部类;A类就是B类的外部类
1.成员内部类
2.静态内部类
3.局部内部类
4.匿名内部类

浙公网安备 33010602011771号