面向对象的三大特性
一、封装
1.1 什么是封装?
是指隐藏对象的属性和具体实现细节,仅提供对外的访问,面向对象的封装是用类来封装,来实现数据(filed)与功能(method)的封装。
1.2 封装的好处
提高了代码的复用性与安全性。
1.2 封装的核心思想
对于使用者而言,只需了解其访问方式即可,不需要知道具体的实现细节。
1.3 权限修饰符
private、default、protected、public
1.3.1 权限修饰符的作用范围
private :私有的,范围:只能在本类中可用。
default :默认的,如果不加修饰符,此修饰符则是默认修饰符,不会显示出来,范围:,表示的是只能在同一个包中使用。
protected:受保护的,范围:同一个包,同一个类中,不同包的子类中。
public:公共的,范围:同一个项目中的所有包、所有类中。
1.3.2 权限修饰符如何使用
- private、default、protected、public都可以修饰成员变量、成员方法、静态变量、静态方法
成员变量:一般用private修饰,一般操做成员变量是通过 setter与getter方法来操作。所以一般用private修饰。
成员方法:一般用public修饰
静态变量:一般用public修饰,静态变量属于类所有,对象也可以共同操作,所以一般使用public
静态方法:一般用public修饰,静态方法属于类所有,一般在别的类中,通过类名.静态方法来操作,所以一般使用public来修饰
- private、default、protected、public也都可以修饰构造方法
如果这个类需要被实例化,那么该类的构造方法建议使用public来修饰。
如果这个类不需要被实例化,那么该类的构造方法就必须使用private来修饰。例如Arrays类。我们一般使用Arrays类是使用该类的静态方法,直接使用Arrays.静态方法名(实参列表)。
- default、public 可以修饰类,private、protected不能修饰类
一个源文件中,只能有一个类被public修饰,所以源文件名也必须与被public修饰的类名保持一致。
二、继承
2.1 继承的本质
把一些类的共同属性与行为抽取成一个父类,即 向上提取。
2.2 继承的语法
class Person() {}
class Student extends Person {}
此处Person为父类,student类为子类
父类也可称为“超类”,子类也可称为“派生类”。
2.3 继承的特点
子类可以继承父类的成员属性与成员方法,也可以拥有自己的特有的成员属性与成员方法。
即:子类对父类的扩展
2.4 继承的好处
继承大大的提高了代码的复用性,也提高了开发效率,继承让类与类之间产生了联系,也为多态的出现做了技术铺垫。
注意:继承是一把双刃剑,如果父类代码更改,则继承他的所有子类的代码也会出现变动,这违反了程序开发的“低耦合”的特性。
2.5继承的注意点
a) java 中的继承是单继承,即一个父类可以有多个子类,一个子类不能继承多个父类
c++中的继承是多继承
b)在java语言中,可以多重继承,即A继承B,B继承C,这也就形成了一个继承链
c)如果一个类中没有显示的继承某个类,那么这个类默认继承了“ java.lang.Object ”类,“ java.lang.Object ”类是所有类的老祖宗类。也就意味着所有的类都继承了“ java.lang.Object ”的方法。
三、多态
什么是多态?
父类引用指向子类对象
实现多态的条件有哪些?
1.继承是实现多态的前提
2.子类必须重写父类的方法
3.父类引用指向子类对象
多态的实现场合?
出现在返回值类型中,返回值可以是返回值类型的任意子类对象
出现在形参中,传入的实参可以是形参类型的任意子类对象(简易的工厂)
/**
* 方法的返回值类型为父类类型,则返回值可以是该父类的任意子类对象。
*/
public static Animal createAnimal(String name) {
switch (name) {
case "tiger":
return new Tiger();
case "pig":
return new Pig();
case "cat":
return new Cat();
case "dog":
return new Dog();
default:
throw new IllegalArgumentException("您传入的动物名字不合法,无法批量生产!");
}
}
1.基本数据类型的转换
a)隐式类型转换(自动) 例如:double num = 100;
b)强制类型转换(手动) 例如:int num = (int)1.23;
2.引用数据类型转换
a) 向上转型(自动)
解释:父类引用指向子类对象。
语法:父类类型 对象 = 子类对象;
例如:Animal animal = new Tiger();
优势:隐藏了子类特有的内容,这样提高了代码的扩展性(多态)。
劣势:只能使用父类共有的内容,不能使用子类特有的内容。
b) 向下转型(手动)
解释:子类引用指向父类对象。
语法:子类类型 对象 = (子类类型)父类对象;
例如:Tiger tiger = (Tiger)animal;
优势:不但可能使用父类共有的内容,还能使用子类特有的内容
劣势:使用向下转型的时候,可能会抛出类型转换异常(java.lang.ClassCastException)。
结论:如果某个对象可以执行“向下转型”,那么该对象以前肯定发生过“向上转型”。
instanceof 二元运算符的概述
语法:obj instanceof class
注意事项:
a) obj可以是一个对象,也可以为null。
b) class可以是一个类,也可以是一个接口。
c) instanceof二元运算符返回的结果是一个boolean类型。
instanceof 二元运算符的作用
作用:判断左边的“对象”是否是右边“类或接口”的实例,如果满足条件则返回true,否则返回false。
具体的应用场景:当我们执行“向下转型”的时候,一定要满足“强转对象”是“强转类型”的实例,这样才能做“向下转型”的操作。
什么是编译时类型呢?什么是运行时类型呢?
Animal animal = new Tiger();
编译时类型 运行时类型
编译时看等号左边,运行时看等号右边
instanceof二元运算符编译时的特点
a)当obj为null的情况
当左边obj为null,则右边的“类或接口”可以是任意类型。*
b)当obj不是null的情况* 当右边“类或接口”是左边“对象”的父类、本身类和子类时,编译通过,否则编译失败。*
–> 注意:此处的“本身类”指的就是“编译时类型”。
instanceof二元运算符运行时的特点
a)当obj为null的情况
当obj为null,则返回的结果肯定是false。
b)当obj不是null的情况
当右边“类或接口”是左边“对象”的父类和本身类,返回结果就是true;
当右边“类或接口”是左边“对象”的子类和兄弟类,返回结果就是false。
–> 注意:此处的“本身类”指的就是“运行时类型”。
多态情况下操作成员变量的特点
编译时检查“编译时类型”,也就是查看“编译时类型”中是否包含该成员变量。
运行时检查“编译时类型”,也就是操作“编译时类型”中成员变量。
总结:编译和执行都检查“编译时类型”。
2.多态情况下操作成员方法的特点* 编译时检查“编译时类型”,也就是查看“编译时类型”中是否包含该成员方法。
运行时检查“运行时类型”,也就是调用“运行时类型”中的成员方法。
总结:编译检查“编译时类型”,运行检查“运行时类型”。