封装和多态
# 封装
封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成"类",其中数据和函数都是类的成员
引自百度百科
之所以引用百度百科的定义是因为我需要一个相对权威的解释。在我接触到的很多人中认为封装就是使用 private 修饰成员变量,这种观点我并不认同,我的理解是 private 是封装的形式之一
有些词或者话描述不准确会误导很多初学者,例如在说到面向对象特征的时候,很多人下意识的回答是封装、继承、多态,这样的回答不能说是错误的,但是至少不够准确,因为面向对象的主要特征里面确实有这三种,但是初此之外还有其他的,例如聚合、依赖。所以在描述面向对象特征时,我认为应该说明封装、继承、多态是面向对象的主要特征
封装在 Java 中并没有牵扯特定的语法,我们也仅仅是对类的成员采用不同的访问权限修饰符进行修饰,从而实现这些成员在被访问时需要遵循不同的规则。也就是百度百科中提到的将属性控制在利用我们提供的接口(此处可理解为方法)来实现属性读、写的访问
# 多态
多态分为两种,一种是运行时多态,另外一种,是编译时多态,是由方法重载所导致的一种多态。我们下面讨论的是关于运行时多态
要聊多态先要聊一下引用变量,在 Java 中的数据类型划分为基本数据类型和引用数据类型。基本数据类型很容易理解,这次我们聊一下引用数据类型
当我们的变量的值是一个对象的时候,该变量的值其实是指向了内存空间的,同时该变量也就成为了这段空间的标识。而针对这种类型的变量我们称为引用变量
Java 引用变量同样有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定
关于多态的定义
多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
同时 Java 中的多态存在三个前提
要有继承关系(也可以是接口与实现关系)
子类重写父类的方法(编译时的多态)
父类引用指向子类对象(这种情况就会出现编译时和运行时类型不一致)
public class BaseClass {
public void base() {
System.out.println("父类的普通方法");
}
public void test() {
System.out.println("父类的被覆盖方法");
}
}
public class SubClass extends BaseClass {
@Override
public void test() {
System.out.println("子类覆盖父类的方法");
}
public void sub() {
System.out.println("子类的普通方法");
}
}
public class Demo1 {
public static void main(String[] args) {
// 编译时类型和运行时类型完全一样,因此不存在多态
BaseClass bc = new BaseClass();
// 编译时类型和运行时类型完全一样,因此不存在多态
SubClass sc = new SubClass();
// 编译时类型和运行时类型不一样
BaseClass ploymophi = new SubClass();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 关键字 instanceof
不同的称呼吧有人称 instanceof 为运算符,它的前一个操作数通常是一个引用类型的变量,后一个操作数通常是一个类(也可以是接口)。主要用于判断前面的对象是否是后面的类,或者其子类、实现类的实例
其用法如下:
public class Demo1 {
public static void main(String[] args) {
Object hello = "Hello";
if(hello instanceof String){
System.out.println("字符串是 String 的实例");
}else
if (hello instanceof Object) {
System.out.println("字符串是 Object 的实例");
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
个人理解,该运算符主要是为了避免引用类型在强制转换时出现编译错误