14. 面向对象的特性

一、封装

在面向对象的设计方法中,用于对代码细节进行包装和隐藏的方法。

可以将封装理解为一个保护措施,防止被外部类的代码随机访问。

访问代码的条件:只通过一个接口进行访问。

封装的功能:将程序需要执行的代码流程进行包装和隐藏,同时降低代码的耦合性,便于代码的日常维护和扩展。

封装的特点

  1. 提高了程序的安全性,保护数据
  2. 统一接口
  3. 隐藏代码的细节
  4. 提高代码的易维护性和扩展性

 

this 关键字

此操作可以访问当前类的属性和方法

this的用法:

Java面向对象的特性_父类

这是在类当中的操作

 

将此类的操作调用并打印:

Java面向对象的特性_父类_02

在主方法中,创建该类的对象后通过调用该类的方法输入实参后,便可有输出this操作后的结果

 

Private 关键字

与public关键字相对立,俗称属性私有。

与public不同的是,无法直接访问或修改该对象的属性。

Private是访问权限最窄的修饰符,禁止跨包访问。

语法:关键字后为变量的代码结构

例:

private String name;


Java面向对象的特性_构造器_03

当一个类当中存在private关键字,那么后面的成员属性将不能直接访问

若要进行访问就必须创建一个接口

创建接口的方法

创建set 和 get:

  1. 首先创建一个set方法 用于成员变量值的设定

Java面向对象的特性_抽象类_04

2.再通过get方法 将设定的变量值返回给成员属性

Java面向对象的特性_抽象类_05

设置了set方法和get方法后 在主方法中进行调用

  1. 使用接口

Java面向对象的特性_构造器_06

使用封装这一功能 使程序变得结构化 代码变得更容易理解 对于之后功能的扩充有一定的帮助。

 



 

二、继承

继承的实质指的是一个类获取到另一个类对象属性的方法,将类进行抽象化,并按照一定结构划分。

继承被用来对程序进行扩展,可以在原有的程序中继续编写新添加的代码。提高了工作效率,使代码结构分明。

继承的特性:

  1. 子类(派生类)继承父类(基类)的属性和方法,具备父类的所有特性。
  2. 单继承性:一个父类可以拥有多个子类,但每一层子类只能存在一个父类的关系。

 

extends 关键字

给类添加一个继承的关系

语法:

public class son extends parent(){};


son(子类)继承parent父类

 

权限修饰符四种表达方式

  1. public 公共 表示最高权限 可以跨包跨类访问
  2. Protected 受保护的 允许当前类和此类的子类访问,不能跨包访问
  3. Default 默认的 只能在当前包当前类访问,其子类和其他包不能访问
  4. Private 私有的 权限最低,只能在当前类中访问

 

super 关键字

此操作可以让当前类可以访问其父类的属性和方法

 

访问父类属性和方法的用法:

1. 创建一个父类

Java面向对象的特性_抽象类_07

在定义类的语句中,含有注释的这一段代码是默认执行的,因为所有的类都存在于Object类当中

  1. 为了方便表示子类和父类之间的关系,创建一个与Parent类有继承关系的类

Java面向对象的特性_内部类_08

在这个测试方法中 就实现了使用super关键字访问父类当中的相关数据

 

加载父类的构造方法:

  1. 显示父类的无参方法

Java面向对象的特性_构造器_09

  1. 显示子类的构造方法

  1. 用主方法创建子类的对象时

Java面向对象的特性_构造器_10

创建子类的对象之前 程序会提前加载类的构造器 如果此类与其他类具备继承关系 则会优先加载其父类的构造方法

但是加载的构造方法要么是无参数的构造,要么是有参的构造,两者只能取其中一个

 

super与this的区别:

  1. 访问的对象不同,super是访问其父类的方法和属性
  2. 使用条件不同,super必须在有继承关系的类中使用

super的注意事项:

  1. 当创建含有继承特性的对象时,会将其父级的构造器一同加载
  2. 创建对象的构造器具有唯一性,要么调用自身类的构造器,要么调用父类的构造器
  3. 继承性,当其父类当中没有无参构造器,那么子类的无参构造将会无法创建

 

方法的重写

在满足继承关系的前提下,子类对父类方法函数进行修改或覆盖的操作。

特点:子类重写的函数与父级类的函数的结构相同(函数名 参数类型),函数内代码不相同

 

重写方法的操作:

在两个类确定谁继承谁后,在子类中创建一个与父类相同名字相同类型的方法,结果则是子类覆盖了父类的方法

Java面向对象的特性_构造器_11

Man类继承People类

 



 

三、多态

不同类型的对象指向相同的类,在程序运行时实现不同功能的方法

多态相当于在同一接口中使用不同的实例化执行不同的操作

多态的用处:使程序具有可扩展性,可以实现不同对象的通用性

多态的优点:1. 可替换性 2. 可扩展性 3. 接口性 4. 灵活性

多态的前提条件:

  1. 继承
  2. 子类重写父类
  3. 父类的引用指向子类

由于多态提高了创建对象的灵活性,可以使用不同的引用类型

创建对象的格式:

Man boy = new Man();


左边的子类的引用类型指向子类,也可以为有关联类(父类)的引用

右边的实际类型是确定的,一般指向是哪个类的

 

在Man类继承People类的案例中:

Java面向对象的特性_构造器_12

可以看出虽然创建的对象不同,但是结果都是子类的

原因:由于子类重写了父类的方法,不管是父类的引用还是子类的引用使用的都是被子类覆盖的方法。若使用的方法是各自独有的,则会导致结果的不同

 

多态的注意事项:

  1. 重写的方法仅限于非静态方法,因为静态方法调用是哪个类就是用哪个类的方法
  2. 在多态中子类可以调用自己的方法,重写父类的方法
  3. 父类不能直接调用子类独有的方法

 

instanceof 关键字

用于判断对象是否属于这个类的实例。结果为布尔表达式,属于为true,不属于为false

判断公式:a instanceof A

a 对象 A 类

使用instanceof的判断条件:

首先a对象的类与A类是否有继承关系,如果没有关系,则编译报错

实例体现:创建一个父类Person、两个子类Student和Teacher

Java面向对象的特性_内部类_13

  1. 根据instanceof的判断条件可以得知:
    若当前判断对象的从属类跟判断的类一样则表示为true,若当前判断对象的从属类跟判断的类有直接的继承关系,也属于该对象的实例所以结果为true
  2. 根据对象所指向的实际类型判断:
    若对象的引用类型指向的类不是表达式中的类,则判断为false
  3. 根据继承特性判断:
    若对象的类与判断的类没有继承关系,程序在运行时会编译错误

引用类型转换

与基本数据类型的转换方式相同,把子类看成是低一级的类,父类看成是高一级的类。若要把高一级类的对象转换成低一级则需要强制转换,低转高为自动转换

创建父类Person和子类Student的案例:

父类拥有Per方法,子类拥有Stu方法

高转低

Java面向对象的特性_内部类_14

由于创建的student对象类型为父类,要强制转换成子类的引用类型才能使用子类的方法

低转高

Java面向对象的特性_子类_15

对象类型为子类,自动转换为高一级的引用类型可以直接访问父类的方法。但是会失去对象转换前子类方法的访问的权限

 



 

四、Static关键字解析

static关键字可以用来修饰类、成员变量和成员方法。

被static修饰的成员变量称为静态变量。

用来修饰方法则称为静态方法

静态属性、静态方法、非静态属性和非静态方法的各使用方法

Java面向对象的特性_父类_16

静态代码块的特性

静态代码块是与类同时加载,所以静态代码块中的内容不管调用多少次也只能执行一次。用于写入一些初始化参数

比构造器加载得早

静态导入包的操作

Java面向对象的特性_子类_17

 

五、抽象类

在面向对象的概念里,所有的对象都是通过类来描述的。如果反过来,并不是所有的类都可以创建对象的。如果一个类中没有用来描述对象的内容就是抽象类。

抽象类虽不能创建对象,但是具备普通类的其他功能,可以包含成员变量、成员方法和构造器。

特性:抽象类的方法必须被继承才能拿来使用,一个类只能继承一个抽象类。

 

abstract修饰符

Java当中使用abstract修饰符来定义抽象类

public abstract class Abstract Demo{};


抽象类的定义

Java面向对象的特性_构造器_18

抽象类可以包含自己的属性、方法和构造器,但不能通过自身的对象拿来使用

 

抽象方法

abstract不仅可以修饰类,还可以修饰方法。

注意点:

  1. 抽象方法不能被定义,所以需要重写才能进行定义
  2. 若一个类中包含了抽象方法,那么这个类也必须定义为抽象类

Java面向对象的特性_内部类_19

 

继承抽象类

抽象类只能被一个类继承。

继承抽象类的前提:

  1. 重写抽象类的抽象方法
  2. 这个类也声明为抽象类

Java面向对象的特性_内部类_20

若继承抽象类的子类也声明为抽象的,那么该类也不能创建对象

 



 

六、接口

接口是一个Java抽象类型的集合。一个类继承了一个接口,从而来继承这个接口中的所有抽象的方法,使Java具有多继承性。

接口的特性:

  1. 被接口定义的属性为常量,不得修改。隐式指定为 public static final
  2. 接口定义的方法为隐式抽象的,不能写入其内容。隐式指定为 public abstract
  3. 接口可以声明方法,但不能实现

定义接口并实现

interface关键字

接口不是一个类,不能写入方法的内容。

Java面向对象的特性_父类_21

接口定义变量

  1. 在接口中可以声明变量,变量的类型可以是各种类型。
  2. 必须是public static final所修饰
  3. 灰色部分可以忽略不写

Java面向对象的特性_子类_22

接口定义方法

  1. 接口跟普通类一样,可以定义多个方法,但是方法的类型必须是抽象的。
  2. public abstract所修饰

Java面向对象的特性_父类_23

在jdk1.8版本的新特性:接口支持使用default权限的方法

default void ran(){};


 

实现接口方法

使用implement关键字让一个类实现这个接口

实现前提:1. 必须重写接口的所有方法。2. 该类也是被abstract修饰符修饰

Java面向对象的特性_内部类_24

需要注意的是:若该类实现了接口,其性质也转变为抽象类,不能被直接实例化

总结

接口和普通类的相同点:

  • 可以定义成员变量和成员方法

接口和普通类的不同点:

  • 接口不能实例化
  • 接口没有构造方法
  • 接口中定义的方法都是抽象类型的
  • 接口不是被继承,而是被实现
  • 接口具有多继承性,一个类可以实现多个接口

 



 

七、内部类

在Java中,还存在一些比较特殊的创建类的方法,类似于类当中的嵌套操作。

根据不同的嵌套操作进行分类

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类

 

成员内部类

在A类中再定义另外一个B类,A类为B类的外部类,B类为A类的内部类

案例:

Java面向对象的特性_构造器_25

成员内部类跟普通类的共同点,可以创建对象。

对于内部类方法调用与外部类的区别:需要通过外部类的对象进行内部类的实例化。

通过外部类对象创建内部类的构造方法并赋值给Outclass.Inclass引用类型的内部类对象in

 

内部类具备普通类没有的特性:可以访问外部类的私有属性或方法

访问私有属性的案例:

Java面向对象的特性_子类_26

 

静态内部类

可以用public static关键字修饰的类称为静态内部类

创建条件:必须在一个类之中定义

案例:

Java面向对象的特性_子类_27

静态内部类可以直接调用外部类的静态属性和方法,但不能调用外部类的非静态变量和方法

静态内部类注意事项:在静态内部类中不可以定义抽象方法

 

局部内部类

和局部变量特性相似,作用域只限于方法当中的类,因此只能在这个方法当中被使用

案例:

Java面向对象的特性_构造器_28

局部内部类中不可以定义静态变量和属性,所有的变量和属性这个方法之外不能被其他类调用

 

匿名内部类

不需要定义对象的名字就可以实现调用该类属性和方法的操作

案例:

Java面向对象的特性_抽象类_29