(PS:不好意思,鸽了一天,昨天玩去了)
面向对象的对象的三大特征
-
封装
Java代码规范
- 将类的属性封装在类中,不允许在类的外部直接访问,保护数据的安全,使内容可控
- 只能通过被授权的方法才能对数据进行访问
- 类的基本原则就是封装
实现方式:
- 将属性私有化——使用private修饰
- 提供对外访问的方式,用于赋值,取值——用public修饰方法,生成对应的getter和setter方法
2.继承——可以让一个类继承自另一个类,此时该类会继承另一个类中的属性和方法
继承的的类被称为子类,被继承的类被称为父类(超类/基类)
继承是一种
is a
的关系实现方式
class 子类 extend 父类
作用:1.代码复用,将多个子类中相同的属性和方法放到父类中
2.功能扩展:子类可以有自己独特的属性和方法
特性:
Java只支持单继承,就是一次只能继承一个,但是可以多层继承,即继承的传递,
class B extend A{} class C extend B{}
继承的范围(子类可以继承父类的内容):
- 父类的public,protected,默认修饰的属性和方法库被子类继承(同包的情况下)
- 父类的private修饰的属性和方法不能被子类继承
- 父类的构造方法不能被子类继承(构造方法名必须与类名相同,而类名不可能相同)
构造方法的调用:
- 创建子类对象默认会自动调用父类无参的构造方法。(必须保证父类有无参构造)
-
从子类开始,逐级往上调用父类的构造方法,直到Object类(Object类是最高层的父类,如果没有写extend则默认继承Object类),再层层返回子类,执行后续代码
- 创建子类对象时必须会调用父类的构造方法,而调用父类构造方法也就创建了父类的对象,所以当创建子类对象时,也创建了父类对象,只不过这个父类对象不是独立存在的,而是和子类对象合为一个整体
super关键字:
-
表示父类对象的引用,只能在子类中使用
-
可以使用
super()
调用父类的构造方法,必须位于第一行 -
可以使用
super.
访问父类的属性和方法,解决父类和子类中成员同名的问题this关键字:
-
表示当前对象的引用,只能在方法中使用
-
可以使用
this()
访问当前类中的重载的构造方法,必须位于第一行 -
可以使用
this.
访问本类中的属性和方法,解决全局变量和局部变量同名的变量注:调用构造方法时this()和super()都只能放在第一行,所以不能同时使用
方法重写
子类中的方法,与父类中的方法的名称,参数列表,返回类型一样,我们就说子类重写了父类的方法,称为方法重写override
- 在父子类中
- 方法名相同
- 参数列表相同
- 返回类型相同或是子类
- 访问修饰符不能缩小,即访问权限不能缩小
- 子类不能抛出比父类更大的异常
作用:用来重新定义子类的行为,解决父类和子类的差异性
面试:方法重载和方法重写的区别
多态——多态是具有表现多种心态的能力的特殊,即一种事物,具有多种形态
自动类型转换——将父类的引用指向子类的对象,称为向上转型,会自动进行类型转换
- 通过父类引用变量调用的方法时子类重写后的方法,不是父类的方法
- 通过父类引用变量无法访问子类特有的属性和方法
强制类型转换——将一个指向子类对象的父类引用赋给一个子类的引用,称为向下转型,必须进行强制类型转换
- 向下转型后可以访问子类特有的属性和方法
- 必须转换为父类指向的真实子类类型,否则会出现类型转换异常 ClassCastException
- 向下转型是不安全的,可以在转换时使用
instanceof
操作符判断对象的类型,避免类型转换异常
实现多态的条件:
-
-
继承的存在(继承是多态的基础,没有继承就没有多态)
-
子类重写父类的方法(多态下调的是子类重写后的方法)
-
父类引用变量指向子类对象(向上转型)
多态的优点:
- 减少代码量
- 提高可扩展性和可维护性
抽象类和接口
final关键字
final表示最终的,可以用来修饰变量,方法,类
修饰变量
被final修饰的变量,称为常量constant
,常量的值是不能被修改的
被static final
修饰的变量,称为静态常量,一般也称为常量
修饰方法
被final修饰的方法,不能被重写
修饰参数
被final修饰的参数,只能读取,不能修改
抽象类
如何防止父类被实例化?——防止类不能实例化。也就是这个类不能被“new”出来,通过标记该类为抽象类,编译器就知道不管在哪里,这个类就是不能创建任何类型的实例。
如何保证子类必须重写父类的方法?——所以抽象类或者接口,抽象类的子类可以部分重写父类的方法,但这个这类还是一个抽象类(只有没有抽象方法才属于抽象类)
- 被
abstract
修饰的类,称为抽象类- 定义方式
public abstract class 类名()
- 抽象类不能被实例化,即不能使用new创建一个对象,只能被继承
- 定义方式
- 被
abstract
修饰的方法,称为抽象方法:- 定义方式
public abstract 返回值类型方法名()
- 抽象方法只有声明,没有具体实现,即没有方法体,以分号结尾
- 定义方式
- 抽象类中可以有抽象方法,也可以没有抽象方法
- 含有抽象方法的类,必须为抽象类
- 子类继承抽象类后,必须实现/重写抽象类中所有的抽象方法,否则子类仍然为抽象类
- 抽象类中可以有构造方法,但不是来创建对象的,而是用来初始化成员属性的
接口
如果一个抽象类中只有抽象方法和常量值,则可以定义为接口interface
(从本质上讲,接口是一种特殊的抽象类,只能包含常量和方法的声明)
inrerface 接口名{
常量;
抽象方法;
}
-
接口中的属性,默认被
public static final
修饰,即接口中只有常量 -
接口中的方法,默认被
public abstract
修饰,即接口中只有抽象方法 -
接口中没有构造方法,不能实例化接口
实现接口
class 类名 extends 父类 implement 接口名
实现接口的类,称为实行类
实现类必须实现接口中所有的抽象方法,且方法必须使用public修饰,否则为抽象类
- 一个类可以实现多个接口,多个接口之间以逗号隔开
- JDK1.8及以后,可以使用
default
关键字修饰方法,此时方法可以有方法体,但一般为空方法(简化实体类的操作,无需实现所有的方法) - 一个接口可以继承多个其他接口,添加新属性和抽象方法,但接口不能继承类
- 在Java中支持接口的多层继承,但不支持类的多层继承
作用:
-
间接实现多继承
-
通过接口定义规范和标准
-
将标准的定义和实现分开
-
(建议面向接口编程,提高扩展性)
接口和抽象类的比较
相同点:
- 接口和抽象类都不能实例化
- 都可以包含抽象方法
不同点:
- 接口中只有静态常量,抽象类中还可以有普通成员变量
- 接口中只有抽象方法,抽象类中可以有非抽象方法(使用
default
关键字时接口也可以有非抽象方法) - 接口中不包含构造方法,抽象类中可以包含构造方法
- 接口支持多继承,抽象类不支持多继承
、
- 接口和抽象类都不能实例化
- 都可以包含抽象方法
不同点:
- 接口中只有静态常量,抽象类中还可以有普通成员变量
- 接口中只有抽象方法,抽象类中可以有非抽象方法(使用
default
关键字时接口也可以有非抽象方法) - 接口中不包含构造方法,抽象类中可以包含构造方法
- 接口支持多继承,抽象类不支持多继承
、