面向对象
什么是面向对象
类和对象(抽象与具体)
类:属性和行为的集合,可以看成是一类事物的模板
对象:一类事物的具体体现,对象是类的一个实例。
封装
什么是封装?
隐藏对象的内部实现细节,外部不能直接操作和修改。封装可以被认为是一种保护屏障,防止其中的数据被随意的访问
继承(多态的前提)
继承解决的问题
共性抽取
继承的好处
提高代码的复用性和拓展性
继承的特点
1.单继承,可以有多级继承
2.子类继承父类,可以使用父类的属性和方法
3.优先使用子类本身的属性和方法,没有再向上找
多态
什么是多态
【定义】:同一种行为具有不同的表现形式
【概念】:父类引用指向子类对象
Animal a = new Dog()
【特点】
多态中父类引用只能调用父类的属性和方法,不能调用子类的属性和方法
多态中的方法重写
父类类型引用调用此方法,优先执行子类中的方法
多态的好处
可拓展性,可维护性更强
多态的应用
1.作为形参 e.g Object类中的equals方法
2.作为返回值
向上转型(装箱)
多态的核心,可以默认转,一定是安全的。类似于自动类型转换
【含义】:可以把它都当成父类来使用,只有当方法重写才调用子类
向下转型(拆箱)
需要强转,和本来创建的对象的类型不一致会出现类型转换异常
【本质】:将父类对象,还原成为本来的子类对象
关键字instanceof
【格式】:
if (对象 instanceof 类名称) {
类名称 new_name = (类名称) b;
}
用于规避向下转型后的隐患。当对象能匹配对应类型时,可进行强转
访问修饰符
public | protected | default | private | |
---|---|---|---|---|
同一个类 | √ | √ | √ | √ |
同一个包(子类与无关类) | √ | √ | √ | × |
不同包的子类 | √ | √ | × | × |
不同包中的无关类 | √ | × | × | × |
方法的重写(Override)
1.在继承关系中,方法名称,参数列表相同
2.子类方法的返回值必须【小于等于】父类方法的返回值范围
3.访问修饰符必须【大于等于】父类方法的访问修饰符
90%以上情况返回值和修饰符都是相等情况
方法的重载(Overload)
同一个类中,方法名称相同,参数的数据类型、顺序、个数不同,与修饰符,返回值类型无关。
this
1.指向对象本身,可以调用成员变量,成员方法。
如果本类不存在,则可调用父类的成员变量,成员方法
2.在构造方法中,通过this关键字调用本类其他构造方法
super
1.指向父类的引用,可以调用父类的成员变量或成员方法
2.在构造方法中,可以显示的调用父类的构造方法。
构造方法中,this()和super()不能共存,默认为隐式super()
return
1.没有返回值的情况下,表示结束当前方法,直接返回到方法调用处
2.返回一个值
abstract
抽象类作用
1. 可被子类继承,提供共性属性和方法
2. 可声明为引用,更自然的使用多态
抽象方法
1.被abstract修饰的方法为抽象方法,只有方法声明,没有方法体。
2. 必须包含在抽象类中
abstract注意事项
1. 不能直接new抽象类对象,如果创建,编译报错。只能创建其非抽象子类的对象
2. 子类继承抽象类后,必须重写父类中所有的抽象方法,否则,编译无法通过,除非子类也是抽象类
3. 可以有构造方法,是供子类创建对象,初始化父类使用的。
4. 抽象类中,不一定有抽象方法,但是有抽象方法一定是抽象类。
static
静态变量(类属性):
【格式】:类名称.静态变量
静态方法:
【格式】:类名称.静态方法()
静态变量
静态方法(类方法)
不属于对象,属于类
【建议】:建议通过类名称调用,不推荐用对象名称调用,因为用对象名称调用容易误以为它是一个普通的成员变量或成员方法。
静态特点
1.允许直接访问静态成员
2.静态方法不能直接访问非静态成员,同加载时期有关
3.静态方法中不允许使用this或super关键字,
4.静态方法可以继承,不能重写,没有多态
代码块
动态代码块
执行时机:初始化成员属性之后,构造方法之前
【特点】实例化多个对象会触发多次动态代码块
静态代码块
执行时机:类加载时,静态代码块执行
特点:无论实例化多少对象,只触发一次静态代码块
【典型用途】:用来一次性地对成员变量进行赋值
final
1.修饰类:最终类不能被继承
2.修饰的方法:不能被重写
3.修饰的成员属性必须要赋值
赋值的时机:初始化、动态代码块、构造方法(每个构造方法都必须要赋值)
4.修饰静态属性必须要给赋值
赋值的时机:初始化、静态代码块
5.修饰局部变量的基本类型和引用类型
基本类型:值不能改变
引用类型:地址不能改变,值可以改变
【问题】:
构造方法为什么不能被继承?
因为构造方法必须要同类名相同,父类子类不能同名,故不能被继承,也不能被重写。
为什么我们要尽量把属性设为private?
为了不让对象直接通过属性名来使用和修改,而是通过getter/setter方法,这样属性就不会被附上任何非法的值了。
成员变量与局部变量的区别
1.类中位置不同
成员变量:类中,方法外
局部变量:方法中或方法声明上
2.作用范围不同
成员变量:类中
局部变量:方法中
3.在内存中位置不同
成员变量:堆内存
局部变量:栈内存
4.生命周期不同
成员变量:随对象创建而存在,随对象消失而消失。
局部变量:随方法调用而存在,随着方法的调用完毕而消失。
为什么要配置环境变量
如果没有配置好环境变量,我们就必须告诉操作系统绝对路径,配置好环境,就可以在任何目录位置下都可以直接输入命令,而不用输入长长的路径。
面向对象的设计原则:
开闭原则:OCP(Open-Closed Principle)
对外新增的代码持开放状态,对内修改的代码持关闭状态
类加载顺序
如果类还没有被加载:
1、先执行父类的静态代码块和静态变量初始化,并且静态代码块和静态变量的执行顺序只跟代码中出现的顺序有关。
2、执行子类的静态代码块和静态变量初始化。
3、执行父类的实例变量初始化
4、执行父类的构造函数
5、执行子类的实例变量初始化
6、执行子类的构造函数
如果类已经被加载:
则静态代码块和静态变量就不用重复执行,再创建类对象时,只执行与实例相关的变量初始化和构造方法。
【建议】静态变量放在静态代码块之前
equals方法的重写