(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
关键字时接口也可以有非抽象方法)接口中不包含构造方法,抽象类中可以包含构造方法接口支持多继承,抽象类不支持多继承、
外链:接口和抽象类比较 (干货)