第五章 java类与对象
1.面向对象
java是面向对象的语言。面向对象(OOP 即 Object Oriented Programming)是一种思想,任何事物都可以看做是一个对象。我们打个比方来类比一下,以动物为例子,动物可以看做是一类事物的总称,可看做为类。其可以是老虎,狮子,或者人…,这就是动物这个类具体的实现,即对象。动物有吃饭,奔跑的行为,我们可以看做为实例的方法,有耳朵眼睛和鼻子,这些就是实例的属性。总而言之,面向对象思想是典型的看起来简单,但深入理解很难的类型,需要相当长时间的摸索和相当多的编程经验积累才能彻底掌握,对OOP的理解程度与程序员代码水平和架构设计息息相关。
2.面向对象的特性
2.1 继承
继承是面向对象的基本特征之一,继承机制允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。类似下面这个图:
2.2 封装
封装就是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别,将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。
封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用
类的成员。
2.3 多态
多态同一个行为具有多个不同表现形式或形态的能力。是指一个类实例(对象)的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。
2.3.1多态的优点:
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
多态存在的三个必要条件: 继承 重写(子类继承父类后对父类方法进行重新定义) 父类引用指向子类对象
注:面向对象的概念以及三大特性虽然是初级概念,但要真正理解却是要长时间的积累+感悟,关于此概念在后面设计模式和设计原则一块还会重新详细的讲解。
本段摘自此博客
3.接口和抽象类的异同
3.2共同点
- 都不能被实例化。
- 接口的实现类和抽象类的子类只有全部实现了接口或者抽象类中的方法后才可以被实例化
3.2不同点
- 接口只能定义抽象方法不能实现方法,抽象类既可以定义抽象方法,也可以实现方法。
- 单继承,多实现。接口可以实现多个,只能继承一个抽象类。
- 接口强调的是功能,抽象类强调的是所属关系。
- 接口中的所有成员变量 为
public static final
, 静态不可修改,当然必须初始化。接口中的所有方法都是public abstract
公开抽象的。而且不能有构造方法。抽象类就比较*了,和普通的类差不多,可以有抽象方法也可以没有,可以有正常的方法,也可以没有。
3.3 接口和抽象类的侧重点
3.3.1抽象类的定义
抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。
3.3.2抽象类的作用
1、用于隐藏 对类型进行隐藏,我们可以构造出一个固定的一组行为的抽象描述,一个行为可以有任意个可能的具体实现方式。这个抽象的描述就是抽象类。(参考多态)
2、用于拓展对象的行为功能
这一组任意个可能的具体实现表现为所有可能的子类,模块可以操作一个抽象类,由于模块依赖于一个固定的抽象类,那么他是不允许修改的。同时通过这个抽象类进行派生,拓展此模块的行为功能。(参考开放闭合原则)
3.3.3接口的定义
接口泛指实体把自己提供给外界的一种抽象化物(可以为另一实体),用以由内部操作分离出外部沟通方法,使其能被内部修改而不影响外界其他实体与其交互的方式。
3.3.4接口的作用
Java单继承的原因,所以需要曲线救国 作为继承关系的一个补充。
把程序模块进行固化的契约,降低偶合。把若干功能拆分出来,按照契约来进行实现和依赖。(依赖倒置原则)
定义接口有利于代码的规范。(接口分离原则)
4.举例
以上概念比较晦涩难懂,咱们举个动物的例子来加深一下印象
4.1 接口
我们来创建一个生命周期接口LifeCycle,所有的动物都有生命周期,所以我们抽象出这么一个接口
package com.hqa;
public interface LifeCycle {
/**
* 生
*/
void born();
/**
* 老
*/
void old();
/**
* 病
*/
void ill();
/**
* 死
*/
void die();
}
4.2抽象类
创建一个抽象的animal类
package com.hqa;
public abstract class Animal implements LifeCycle{
@Override
public void born() {
System.out.println("出生了...");
}
@Override
public void old() {
System.out.println("老了...");
}
@Override
public void ill() {
System.out.println("生病了...");
}
@Override
public void die() {
System.out.println("死了...");
}
}
4.3猫科动物类
package com.hqa;
public class CatKindAnimal extends Animal{
/**
* 构造函数
*/
public CatKindAnimal(String name){
this.name = name;
}
/**
* 姓名
*/
public String name; //共有属性
/**
* 花色
*/
private String color; //私有属性
/**
* 拥有技能 爬树
*/
public void tree(){
//TODO ..
}
}
4.4 鱼类
package com.hqa;
public class FishKindAnimal extends Animal{
/**
* 拥有技能游泳
*/
public void swim(){
//TODO ..
}
}
4.5神仙类
package com.hqa;
public class SuperAnimal extends Animal{
/**
* 神仙是长生不死的,可以通过重写die方法来实现
* 但是这样做并不是一个好的设计,后面我们会讲到接口隔离原则
*/
@Override
public void die() {
System.out.println("神仙不会死...");
}
}
一个类可以包含以下类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
4.6 实例
对象是根据类创建的。在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步:
声明:声明一个对象,包括对象名称和对象类型。
实例化:使用关键字new来创建一个对象。
初始化:使用new创建对象时,会调用构造方法初始化对象。
下面我们来实例化一下:
package com.hqa;
public class Test {
public static void main(String[] args) {
//实例化了一个名叫tom的猫科动物
CatKindAnimal cat = new CatKindAnimal("TOM");
cat.born();
cat.die();
//实例化了一个神仙
SuperAnimal sup = new SuperAnimal();
sup.die();
}
}
运行可以看到如下结果:
出生了...
死了...
神仙不会死...
上一篇: OpenSSL CentOS 7 安装
下一篇: 前端工程化