Java学习-4
面向对象的三大特征之一:继承性
主要解决问题:共性抽取
继承关系当中的特点:子类可以拥有父类的“内容”,子类还可以拥有自己专属的内容
定义一个父类的格式(就是定义一个普通类的格式):
Public class 类名称 {
Public 方法类型 方法名称{
}
}
定义一个子类的格式:
Public class 子类名称 extends 父类名称{
//........
}
如果父类中的变量与子类中的变量重名时,创建的对象是谁就优先用谁当中的变量。
如果父类中的方法与子类中的变量方法时,创建的对象是谁就优先用谁当中的方法。
区分父类的成员变量、子类的成员变量、局部变量:
局部变量: 直接使用
子类的成员变量:this.成员变量名
父类的成员变量:super.成员变量名
父子类的构造方法访问特点:
子类必须使用父类的构造方法,不写则默认使用一个super();如果使用则只能使用一次,且必须在第一条语句的位置。
super关键字的用法
- 访问父类的成员方法
- 访问父类的成员变量
- 访问父类的构造方法
继承的3大特点
单继承(一个类的父类只能有一个),多级继承(一个父类上面可以有多级父类,最高父类是java.long.Object),多子类(一个父类可以有多个子类)
抽象方法
用处:类当中不确定一个方法其内容是什么则该方法可以为抽象类
结构:在方法的返回值前面加是一个abstract关键字,去掉大括号,但必须是要在抽象类中才可以定义一个抽象方法,抽象类的结构在class前加上一个abstract关键字。
使用方法:
例:主方法
package peizeng;
public class text {
public static void main(String[] args) {
zi zi = new zi();
zi.fu();
}
}
父类中的抽象类及抽象方法
package peizeng;
public abstract class fu {
public abstract void fu();
}
子类方法对父类方法中抽象方法的覆盖
package peizeng;
public class zi extends fu {
public void fu() {
System.out.println("子类方法执行啦!!!");
}
}
如果父类是抽象类,则子类必须覆盖父类中所有的抽象方法,否则错误,除非子类也是一个抽象类
接口
接口就是一种公共的规范标准
定义一个接口的基本格式:
Public interface 接口名称 {
//接口内容
}
接口内容包括:常量,抽象方法,默认方法,静态方法,私有方法。
接口的使用步骤:
1.接口不能直接使用,必须有一个“实现类(类似于子类)”来“实现”该接口
格式:
Public class 实现类名称 implements 接口名称{
//........
}
- 接口的实现类必须覆盖重写(实现)接口中所有的抽象方法
- 创建实现类的对象,进行使用
接口的默认方法
什么是接口的默认方法,即当接口需要升级时(添加新的抽象方法),会导致已经定义好的接口类出现错误,所以如果把添加的新的抽象方法改为默认方法,就不会出现这样的情况,定义好的接口类会默认拥有一个默认方法。
默认方法的定义:
Public default 返回值类型 方法名称(参数列表){
//方法体
}
接口的静态方法
静态方法的定义:
public static 返回值类型 方法名称(参数列表){
//方法体
}
使用方法:使用时直接通过(接口名.静态方法名)调用,不能通过实现类对象调用。
接口的私有方法
当一个方法只希望在接口中被使用,不希望在实现类中使用,即可定义为私有方法。
- 普通私有方法:解决多个默认方法之间重复代码问题
格式:
Private 返回值类型 方法名称(参数列表){
方法体
}
- 静态私有方法:解决多个静态方法之间重复代码问题
格式:
Private static 返回值类型 方法名称(参数列表){
方法体
}
接口的常量
即成员变量
格式:
Public static final 数据类型 常量名称 = 数据值;
注意:
这3个关键字可以省略不写,必须赋值,一旦赋值则永远不能改变,名称大写。
调用:接口名.常量名称
关于使用接口的注意事项
- 一个类虽然只能有一个父类,但是可以有多个接口
例:public class 实现类名称 implement 接口名1,接口名2{
//覆盖重写的所以方法
}
2.如果实现的多个接口中存在相同的抽象方法,那么必须进行一次覆盖重写
3..如果实现的多个接口中存在相同的默认方法,那么实现类必须要覆盖重写冲突的默认方法。
4.接口与接口之间也可以出现继承,
例如一个接口需要继承一个或者多个接口:
Public interface 接口名 extend 接口1,接口2,......{
//方法体
}
面向对象的三大特征之一:多态
概念:父类应用指向子类对象
格式:父类名称 对象名 = new 子类名称();
或者 接口名称 对象名 = new 实现类名称();
多态中成员变量的使用规则:
直接使用:等号左边是谁就优先用谁,没有则向上查找
间接使用(通过成员方法访问成员变量):方法属于谁就优先用谁,没有则向上查找,但是如果被子类覆盖则使用被子类覆盖的新方法
多态中成员方法的使用规则:
看new的是谁就优先用谁,没有则向上查找,即:编译看左边,运行看右边。
对象的转型
类似于数据强转,向上只是小范围转向大范围,但是会失去子类方法中特有的方法
向上转型(就是多态写法):
格式:父类名称 对象名 = new 子类名称();
向下转型(将父类对象还原成原来的子类对象,条件:必须是对应的子类对象)
先向上转型,在向下转型
使用instanceof关键字对父类对象进行原来是哪一个子类对象的判断,返回一个布尔值
例:
Animal animal = new Dog();//这是向上转型
if(animal instanceof Dog){
//......
}
Final关键字代表最终的,不可改变的
常见使用方法:
- 修饰一个类:则该类不能拥有子类。Public final class XXX {.....}
- 修饰一个方法:则该类不能被覆盖重写。Public final XXX{......}
- 修饰一个局部变量:如果是基本数据类型,则数据赋值后不能改变,如果是引用数据类型则其地址不能改变。Final int number = 10;
- 修饰一个成员变量:private final XXX xx;则必须直接赋值或者通过构造方法赋值
内部类
即一个类的内部包含另一个类。
分类:成员内部类与局部内部类。
成员内部类:
修饰符 class 外部类名称 {
修饰符 class 内部类名称{
//...
}
//...
}
使用方法:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
如何在内部类中访问外部类的成员方法:外部类名称.this.外部类成员变量名
局部内部类(定义在一个方法内部的类):
修饰符 class 外部类名称{
修饰符 返回值类型 方法名称(参数列表){
class 局部内部类名称{
//......
}
}
}
注意:如果局部内部类要想访问方法的成员变量,则该成员必须为(有效final值)即只能赋值一次。
匿名内部类
当接口的实现类仅需要使用一次的时候,则可以省略实现类改为使用匿名内部类。
定义格式:
接口名称 对象名 = new 接口名称(){
//覆盖重写所有抽象方法
} ;
注意:其在创建对象的时候只能使用唯一的一次