面向对象
OOP(object-oriented Programming):以类的方式组织代码,以对象的组织(封装)数据
三大特性:封装,继承,多态
类与对象
对象是类的一个实例,比如某个人(对象),是人(类)的一个实例
创建和初始化对象
Student student = new Student();
1、分配内存空间
2、进行默认的初始化
3、类中构造器的调用
构造器
调出out目录(输出目标,含.class文件):program structure->Modules->Add Content Root->out
在.class文件中可看到,所有的类都有一个隐藏的public ClassName(){}方法,即构造方法/构造器
1、构造方法必须和类同名,且无返回值;
2、每new一个实例时,都会立即执行构造方法;即:new的本质,就是在调用构造器
3、构造器一般用来初始化值
4、定义有参构造之后,想使用无参构造,需定义一个无参构造(即定义有参构造之后,无参构造会消失)
alt+insert,插入构造器
封装
程序要求高内聚,低耦合
高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
低耦合:仅暴露少量的方法给外部使用
属性私有,get/set方法:alt+insert快捷键生成;
1、提高程序的安全性,保存数据
2、隐藏代码的实现细节
3、统一接口
4、系统可维护性增加了
继承extends
Java中只有单继承,没有多继承;
1、继承是类和类之间的关系,除此之外还有依赖、组合、聚合
2、子类(派生类),父类(基类)
3、private无法继承(public,protected,default,private)
4、所有类都直接间接继承Object类
super
1、在子类的构造器中,隐藏了一句调用父类构造器的代码:super(),且必须放在最前面
2、super必须只能出现在子类的方法或构造方法中
3、super和this不能同时调用构造方法(因为两者都必须在第一行)
this:本身调用者这个对象;没有继承也可用;this()指本类的构造;
super:代表父类对象的应用;必须有继承;super()指父类的构造;
方法的重写(非重载)
父类中的方法无法满足满足子类的业务需求,子类需要将继承过来的方法重写,即覆盖
重写的条件:1、重写发生在具有继承关系的父子类之间
2、返回值类型相同,方法名相同,形参列表相同(重写建议复制粘贴)
3、子类不能比父类更私有(原因:保证父类的方法可以被调用,详见)
4、子类抛出的异常不能比父类更广泛
注意:1、私有方法和构造方法不能被继承,所以不能被覆盖
2、静态方法不存在覆盖(原因涉及多态)
3、重写只能是方法,不存在属性
转型(多态预备知识)
向上转型(upcasting):子类型->父类型,自动类型转换
向下转型(downcasting):父类型->子类型,强制类型转换
转型必须要有继承,否则编译不通过
举例1:向上转型
Cat继承Animal
Animal a = new Cat();
a.move(); //move()父子类中都有,此时成功通过
a.caseMouse(); //catchMouse()为Cat类特有,此时出错
编译期是Animal中的move(),运行时是Cat中的move()(因为new时已在堆中分配内存)
详解
1、Java程序分为编译阶段和运行阶段
2、先分析编译阶段,再分析运行阶段
3、编译阶段编译器检查a的引用类型为Animal,由于Animal.class字节码文件中有move(),所以编译通过;这个过程称为静态绑定,或编译阶段绑定
4、在程序运行阶段,JVM堆内存中国真实创建的对象是Cat对象,因此运行阶段调用Cat对象的move(),此时发生动态绑定,即运行阶段绑定
5、无论Cat类是否重写,一定是调用Cat类中的Move();
6、父类型指向子类型对象,导致编译和运行阶段绑定不同状态,这种机制可以成为一种多态语法机制
问题
a.catchMouse()不通过是因为编译阶段绑定Animal,而Animal中无catchMouse,所以在编译阶段出错;
解决方案
a要调用catchMouse(),可以进行强制类型转换,即向下转型
downcasting使用时机:当调用的方法是子类型中特有的,在父类型中不存在
Cat a2 = (Cat)a;
举例2 向下转型
Animal a = new Bird();
Cat a2 = (Cat)a;
编译通过,但运行时出错,出现著名异常:java.lang.ClassCastException,这种异常通常在向下转型时发生;
向上转型时,只要编译通过,运行也能通过;而向下转型存在隐患;
解决方案
Java规范中要求,强制类型转换之前,建议采用instanceof进行判断,避免ClassCastException异常发生
假设:(a instance Animal)
true:a这个引用指向的对象是一个Animal类型
flase:a这个引用指向的对象不是一个Animal类型
if(a instanceof Cat){
Cat a2 = (Cat)a;
a.catchMouse;
}
问题
如果定义的是静态方法,指向的则是左边的对象,为啥?
instanceof
已知:Studen类和Teacher类是Person类的之类
Object object = new Student()
1、object instanceof Student -> true
2、object instanceof Person -> true
3、object instanceof Object -> true
4、object instanceof Teacher -> false
Person person = new Student()
1、person instance Object -> true
Student student = new Student()
1、student instanceof Person -> true
Person person = new Person()
1、person instanceof Student -> false
instanceof测试时,当被测试者是类的子孙类时,显示true
多态
多态:同一方法可以根据接收对象的不同而采用多种不同的行为方式(原理:向上转型upcasting)
提高程序的扩展里->降低程序的耦合
举例:主人(Master类)喂养宠物,猫(Cat类),狗(Dog类)
喂猫需要在Master类添加一个方法,喂狗又需要一个方法……类与类之间关系紧密,这就是高耦合
多态使用举例
//新建类Pet,内涵eat()喂养方法,Cat类和Dog等都继承Pet类
public class Master {
public void feed(Pet pet){
pet.eat();
}
}
此时加入传来一个Cat的实例,如上一小节中所说编译阶段是Pet类,运行是Cat类,最终调用的是Cat中的eat()方法;
关键在于,将相似的行为抽象成一个方法,写在一个类中,并使有关类继承于它(父类型的引用,指向子类型的对象)
1、Master主人类面向的是一个抽象的Pet,不再面向具体的宠物,面对抽象类的好处在于低耦合,高扩展
2、能使用多态,尽量使用多态
核心:面对抽象编程,而不面对具体编程;
多态的存在条件:有继承关系、子类重写父类、父类引用指向子类对象