面向对象三大特征:封装、继承、多态
面向对象的最终目的是要构建强健、安全、高效的项目,也就是要实现项目的高内聚和低耦合:
应封装的隐藏细节的理念,java提供了访问权限修饰符来控制调用者的访问权限,详情如下:
private:属于类访问权限,表示私有的,只能在当前类中访问,使用private修饰的类、方法、字段,在’离开当前类的作用域之后,调用者就不能直接访问。
(缺省):其实就是什么都不写,其属于包访问权限,表示包私有的,调用者的包必须和当前类(使用 缺省 修饰)的包相同才能访问。
protected:属于子类访问权限,表示受保护的,使用private修饰的类、方法、字段 , 不仅同包中类可以访问,而且即使不同包,但是如果有继承关系,也可以访问。
public:表示全局的公共访问权限,使用private修饰的类、方法、字段,在当前项目中任何地方都可以访问。接口( interface )中的方法默认都是public的。
一般情况下,类的字段都使用private修饰;封装了实现细节的方法,一般也使用private修饰,因为不希望调用者直接访问其实现细节,而是要通过公开的public方法间接调用。
// 公开给调用者访问的public方法 public void doWork(){ methodA(); methodB(); methodC(); } // 三个方法分别封装了部分实现细节 private methodA(){} private methodB(){} private methodC(){}
很少会使用(缺省),即使要使用,也仅仅是暴露给同包中的其他类访问;protected很多时候出现在继承关系中,父类只希望被子类访问的字段和方法时;
从面向对象的角度上说,继承是一种从一般到特殊的关系,是一种 “is a” 的关系,即子类是对父类的拓展,是一种特殊的父类,比如:狗是动物的一种特殊情况,狗属于动物;在这个例子中,动物是父类,狗是子类,狗继承了动物的特征和行为,并在动物的特征和行为的基础之上拓展自己的特征和行为,构成了狗这种特殊的动物。
所以可以基于父类并对其加以拓展,产生新的子类定义,这就是继承;子类可以通过 继承 获得父类原有的字段和方法,也可以增加父类所没有的字段和方法,更是可以覆写父类中的允许被子类 覆盖 的字段或者方法。
在Java中使用” extends ”关键字来表示子类和父类之间的继承关系;在Java中,类之间的继承关系只允许 单继承 ,不允许多继承,一个类只能有一个直接父类。
语法格式:
public class 子类类名 extends 父类类名{ 编写自己特有的状态和行为 }
也就是说一个类只能有一个直接的父类,不能出现类A同时继承于类B和类C。即便不允许多继承,但是 多重继承 是被允许的。以下是一个多重继承的例子:
动物有胎生动物和卵生动物之分,胎生动物有老虎,老虎又分华南虎,东北虎,孟加拉虎等。在继承体系中可以这样来表示:
华南虎——》老虎——》胎生动物——》动物
最终,华南虎通过多重继承获得了老虎、胎生动物、动物的特征和行为。
子类可以继承父类的哪些成员(根据访问修饰符来判断):
方法重写(Override):从父类继承的方法(行为)不符合子类的功能需求,那此时子类就需要重新实现父类的方法,并重写方法体,以实现子类需求。
// 父类 class SuperClass { protected void work() throws Exception {} } // 子类 class SubClass extends SuperClass { @Override protected void work() throws NullPointerException, NumberFormatException {} }
在重写方法父类方法时,使用@Override注解修饰方法,若是重写错误,就会报编译错误,是一大开发利器;这里需要注意的是只有方法会被重写,字段则没有重写一说。
方法重载(Overload): 在同一个类中,方法名字相同,但是因方法参数列表不同而又不同的实现,这样的机制称为方法重载,其实现原则是: 两同一不同 ,返回值并不计入其中。
两同:相同类,方法名(只是方法名,不是方法签名)相同
一不同:方法参数列表不同,包括参数类型、参数个数、参数顺序都必须一致
protected void work() {} protected int work(String str) { return 0;}
this关键字表示当前对象,当前对象就是this所在的这个对象。this主要存在于两个位置:
当一个对象创建之后, JVM 会为对象分配一个引用该对象自身的引用:this。this的使用是为了:
在对象中this表示当前对象,而super则表示当前对象的父类对象。在子类初始化过程中会创建子类对象,但在创建子类对象之前,会先创建父类对象;也就是说调用子类构造器之前,在子类构造器中会先调用父类的构造器,如果没有显式的调用父类构造器,那么默认情况下会隐式的调用父类无参数构造器。
super关键字用于显式调用父类方法、构造器和字段;可以使用super解决子类隐藏了父类的字段情况;在子类方法中,调用父类被覆盖的方法;在子类构造器中,调用父类构造器。
class SuperClass { public SuperClass() {} } class SubClass extends SuperClass { public SubClass() { super(); // 调用父类构造器 } }
上文中提到了隐藏的概念,继承中的隐藏表示会忽略一些特征和方法,比如静态字段和静态方法:
无论是this,还是super,都不能和static一起使用。
在Java中除去Object类之外的每一个类都有一个直接或间接的父类:Object类。也就是说除去Object类之外的类都是Object类的直接子类或间接子类。
比如:
class Person {} class Student extends Person{}
此时Student类的直接父类是Person,Person类的直接父类是Object类,Object类是Student类的间接父类。
Object类是Java的基类,Java中的类都是Object的直接或者间接的子类,Object本身是指对象的意思, 它是所有的对象都具有的共同的行为的抽象类,其他类都会直接或者间接继承于Object类,然后也就拥有了Object类中的方法。
class SuperClass {} 等价于 class SuperClass extends Object {}
通过上文,讲清楚了继承关系, 继承关系是一种”is a”(是一种)的关系 ,也就是说子类是父类的一种特殊情况;既然子类是一种特殊的父类,我们是否可以认为子类对象就是父类类型的对象。
考虑以下的代码:
Animal d = new Dog(); //创建一只狗对象,类型是动物 Animal c = new Cat(); //创建一只猫对象,类型是动物
这个时候,多态就产生了。我们以下面的代码为例,详细解释什么是多态:
Animal a = new Dog();
在上例中,对象a具有两种类型:
编译类型必须是运行类型的父类或与之相同,当编译类型和运行类型不同的时候,多态就产生了。所谓多态是指对象具有多种形态,对象可以存在不同的形式:
Animal a = null; a = new Dog(); //a此时表示Dog类型的形态 a = new Cat(); //a此时表示Cat类型的形态
多态可以是类和类之间的继承关系,也可以是接口和实现类间的实现关系,一般情况下指的都是接口和实现类间的实现关系。
多态的特点:把子类对象赋给父类类型的变量,在运行时期会表现出具体的子类特征,比如父类类型的变量调用子类的方法。
需求:给饲养员提供一个喂养动物的方法,用于喂养动物。
基本数据类型转换:大和小表示的是可存储的容量范围。
自动类型转换:把小类型的数据赋给大类型的变量:
强制类型转换:把大类型的数据赋给小类型的变量。
引用类型的转换:引用类型的大和小,指的是父类和子类的关系。
自动类型转换: 把子类对象赋给父类变量(多态)。
Animal a = new Dog(); Object obj = new Dog();
强制类型转换:把父类类型对象赋给子类类型变量(对象的真实类型是子类类型)。
Animal a = new Dog(); Dog d = (Dog)a;
instanceof 运算符: 判断该对象是否是某一个类的实例。
语法格式:
boolean b = 对象A instanceof 类B; // 判断 A对象是否是 B类的实例,如果是,返回true.
在继承关系中,子类可以继承到父类中部分的成员,那么此时子类是可以修改到父类的信息的,此时的继承关系破坏了封装,让子类拥有了本不该具有的功能。那么这时可以使用” 包含关系”(has a) 的组合关系。
可以这么理解组合关系:把另一个类当作属性来获取其特征和行为。
思考:如果A类想要得到B的功能行为,如若A类是B类的一种特殊情况,就应该采用继承来实现,否则使用组合方式。
class Cat { public void eatMouse() { System.out.println("猫吃老鼠"); } } class XiaoMing { // 把cat类当作属性引入 private Cat cat; public XiaoMing() { cat = new Cat(); } public void killMouse() { cat.eatMouse(); } }
完结。老夫虽不正经,但老夫一身的才华