方法的重写:
* 含义:
* 在子父类继承关系中(或实现关系中),出现了方法名相同,形参列表相同,权限访问级别和返回类型遵循相关规则的现象
*
* 方法重写的前提条件:
* 1.必须有子父类继承关系或实现关系
* 2.子类重写方法的方法名必须和父类方法的方法名相同
* 3.子类重写方法的形参列表必须和父类方法的形参列表相同
* 4.子类重写方法的权限访问级别必须大于或等于比父类方法的权限访问级别,且遵循权限访问级别的修饰范围(详见方法重写的注意事项)
* 5.子类重写方法的返回类型在内存中必须和父类方法的返回类型相同
*
* 方法重写的注意事项
* 1.子类重写父类方法的时候,有些情况即使不满足前提条件,代码也不会编译报错,Java提供了一种用于检测是否满足方法重写的语法规则,
* 如果不满足,将可能运行发生时的错误或逻辑错误提前至编译时期,可以让我提前发现问题,解决问题
* 方法重写的注解
* 含义:
* 用于检测是否满足方法重写的语法规则,如果不满足,编译报错
* 位置:
* 子类重写方法声明上
* 格式:
* @Override
* 修饰符 返回类型 子类重写方法名 () {}
* 2.父类中的私有方法不能被子类进行重写
* 3.父类和子类不在同一个包下,父类的缺省方法不可以被被子类进行重写
* 4.父类中的静态方法不能被子类进行重写,但子类的静态方法代码必须遵循方法重写的语法格式
* 5.父类的最终方法不能被子类进行重写(后面讲解)
* 6.父类的抽象方法必须被子类进行重写(后面讲解)
* 7.子类重写方法的返回类型在代码中,
* 当父类被重写方法的返回类型是void时,必须和父类被重写方法的返回类型相同;
* 当父类被重写方法的返回类型是基本类型时,必须和父类被重写方法的返回类型相同;
* 当父类被重写方法的返回类型是引用类型时,必须和父类被重写方法的返回类型相同或者是该返回类型的子类类型(其实就是后面即将讲解"多态")
继承关系中构造器的特点:
* 1.子类无法继承父类的构造器
* 2.初始化子类成员之前,先初始化父类成员
* 3.当构造器中没有任何的this(实参)或super(实参),JVM的编译器自动给其提供一个无参的super(),供其初始化子类成员之前,先初
* 始化父类成员;一旦构造器有this(实参)或super(实参),JVM的编译器不再进行提供
this关键字的第二种用法
* 场景:
* 子类的构造器
* 格式:
* this(实参);
* 作用:
* 调用本类中其它的构造器
* 含义:
* 当构造器本身无法进行初始化时,通过this(实参)调用本类中其它的构造器完成对象成员初始化
*
* super关键字的第二种用法
* 场景:
* 子类的构造器
* 格式:
* super(实参);
* 作用:
* 根据实参调用父类中的对应的构造器
* 含义:
* 在初始化子类对象成员之前,通过super(实参)调用父类中对应的构造器完成父类成员的初始化
this关键字和super关键字的注意事项
* 1.在代码中,this关键字可以进行打印,super关键字不可以进行打印
* 2.this(实参)和super(实参)必须在构造器中的第一行,否则编译报错
* 3.this(实参)和super(实参)不可以在同一个构造器使用
* 4.在静态方法和静态代码块中不可以使用this关键字或super关键字
* 继承的注意事项:
* 1.类与类之间的关系是继承关系,并且只支持单继承,不支持多继承
* 2.虽然不支持多继承,但是支持多层继承
* 例如:C类继承B类,B类继承A类
* 3.继承关系中的子类和父类是一对相对的概念,不区分"辈分",只区分"直接"和"间接"
* 例如:C类继承B类,B类继承A类
* C类是B类的直接子类,C类是A类的间接子类,B类是A类的直接子类
* A类是B类的直接父类,A类是C类的间接父类,B类是C类的直接父类
* 4.继承关系中,子类只能拥有一个直接父类,但父类可以拥有多个直接子类
* 例如:C类继承B类,D类继承B类,B类继承A类
* 5.所有的类都有一个最顶级的父类Object类
* 当一个类没有任何extends关键字时,JVM让其默认继承Object类(枚举类除外)
Object类
* 类的特点
* 1.Object类是类层次的顶级父类
* 2.所有的对象或数组都可以调用Object类中的方法
* 3.所有的接口都继承Object类抽象形式(暂不涉及)
* 类的位置
* java.lang
* 类的构造器
* public Object()
* 类的方法
* public boolean equals(Object obj)
* 指示其他某个对象是否与此对象“相等”。
* public String toString()
* 返回该对象的字符串表示。
*
* eqauls()和运算符==的区别
* ==既可以比较基本类型数据,也可以比较引用类型数据
* 当==比较基本类型数据时,比较的是基本类型数据值是否相等
* 当==比较引用类型数据时,比较的是引用类型地址值是否相等
* eqauls()只可以比较引用类型数据
* eqauls()比较的是引用类型地址值是否相等
* 如果比较类型重写了Object类的eqauls(),需要按照重写后的规则进行比较
*
* toString()方法的注意事项
* 使用输出语句打印对象名的时候,其实就是打印该对象的toString()的返回内容,char类型数组除外
四种权限访问级别修饰范围从小到大的关系:
* private < 缺省 < protected < public
*
* private权限访问级别(私有的)
* 作用范围:
* 本类内,被private修饰的内容在本类中有效,在本类之外无法进行访问
* 缺省权限访问级别(什么都不写)
* 作用范围:
* 1.兼容private权限访问级别的作用范围
* 2.在同一个包下有效,缺省的内容在同一个包下有效,超出同一个包无法进行访问
* protected权限访问级别(受保护的)
* 作用范围:
* 1.兼容缺省权限访问级别的作用范围
* 2.如果是三级结构(项目,包,类文件),在同一个项目中并且跨包情况下具有子父类继承关系有效,跨包且没有继承关系时无法进行访问
* 如果是四级结构(项目,模块,包,类文件),在同一个模块中,具有子父类继承关系有效,跨包且没有继承关系时无法进行访问,如果在
* 同一项目不在同一个模块下,需要手动修改项目的配置文件后,具有子父类继承关系被protected修饰的内容有效
* public权限访问级别(公共的)
* 作用范围:
* 1.兼容protected权限访问级别的作用范围
* 2.如果是三级结构(项目,包,类文件),在同一个项目中有效,跨项目无法进行访问
* 如果是四级结构(项目,模块,包,类文件),在同一个模块中有效,在同一个项目中不同模块,需要手动修改项目的配置文件后有效,
* 跨项目无法进行访问
*
* 封装思想的核心就是将不同的内容添加不同权限访问级别
*
* 思考:如果存在多个项目,某些数据需要跨项目进行访问,怎么办?
* 序列化和反序列化(第一种序列化和反序列化:对象流)
权限访问级别的补充:
*
* 类文件(class,interface,enum)
* 权限访问级别:
* 只能public和缺省,推荐public
* class中的成员量(成员变量和成员常量)
* 权限访问级别:
* 四种都可以,推荐private
* class中的成员方法
* 权限访问级别:
* 四种都可以,推荐public,private,protected
* class中的成员内部类
* 权限访问级别:
* 四种都可以,推荐缺省,private
* class中的构造器
* 权限访问级别:
* 四种都可以,public,private,protected
* class中的构造器代码块
* 权限访问级别:
* 只能缺省
* class中的静态代码块
* 权限访问级别:
* 只能缺省
* interface中静态常量
* 权限访问级别:
* 只能public,即使没有不写public,JVM的编译器自动填充public
* interface中抽象方法
* 权限访问级别:
* 只能public,即使没有不写public,JVM的编译器自动填充public
* interface中内部接口
* 权限访问级别:
* 只能public,即使没有不写public,JVM的编译器自动填充public
* interface中默认方法
* 权限访问级别:
* 只能public,即使没有不写public,JVM的编译器自动填充public
* interface中静态方法
* 权限访问级别:
* 只能public,即使没有不写public,JVM的编译器自动填充public
* interface中私有方法
* 权限访问级别:
* 只能private
* enum中的枚举对象
* 权限访问级别:
* 只能public,如果显式修饰为public,编译报错
* enum的成员量(成员变量和成员常量,除枚举对象)
* 权限访问级别:
* 四种都可以,推荐private
* enum中的成员方法
* 权限访问级别:
* 四种都可以,推荐public,private,protected
* enum中的成员内部类
* 权限访问级别:
* 四种都可以,推荐缺省,private
* enum中的构造器
* 权限访问级别:
* 只能private,即使没有不写private,JVM的编译器自动填充private
* enum中的构造器代码块
* 权限访问级别:
* 只能缺省
* enum中的静态代码块
* 权限访问级别:
* 只能缺省
* 代码块中的局部成员:
* 权限访问级别:
* 只能缺省
继承关系中的BUG:
* 1.父类存储多个子类相同的属性和相同的行为,希望这个父类不可以被实例化对象,实际上这个父类可以被实例化对象;
* 2.父类的实例方法需要子类们进行重写,但是最终执行肯定是子类的重写后方法,父类被重写方法的方法体就不是很重要了,希望在开发中
* 不编写父类被重写方法的方法体,实际上如果父类被重写方法的方法体省略不写的话编译报错;
* 3.父类的实例方法需要子类们进行重写,希望在忘记重写时,开发环境编译报错进行提示,实际上什么提示都没有
*
* 抽象的出现就是为了解决继承关系中上述的3个BUG
abstract关键字:
* 含义:
* 抽象的
* 修饰:
* 类==>抽象类
* 方法==>抽象方法
*
*
* 抽象类:
* 含义:
* 被abstract关键字修饰的"父类",抽象类也被称之"加强版父类"
* 格式:
* public abstract class 父类类名 {}
* 注意:
* 1.抽象类不可以实例化对象
* 2.抽象类中可以含有构造器,构造器的作用是用来创建子类对象时先初始化父类成员的
抽象方法
* 含义:
* 被abstract关键字修饰,且没有方法体的实例方法
* 格式:
* 修饰符 abstract 返回类型 方法名 ();
* 注意:
* 1.抽象类中可以没有抽象方法,但抽象方法所在的类必须是抽象类
* 2.抽象类的子类必须重写抽象类中所有的抽象方法,否则编译报错,除非该子类也是抽象类