1、多态
表现形式:父类类型 对象名称=子类名称
前提:有继承关系
有父类引用指向子类对象
有方法重写
调用成员的特点:
变量调用:编译看左边:javac编译代码时,会看左边的父类有没有这个变量,如果有,编译成功,如果没有,编译失败;
运行也看左边:java运行代码时,实际获取的是左边父类中成员变量的值
方法调用:编译看左边:javac编译代码时,会看左边的父类有没有这个方法,如果有,编译成功,如果没有,编译失败;
运行看右边:java运行代码时,实际运行的是子类中的方法
因为:成员变量:在子类的对象中,会把父类的成员变量也继承下来,父:name 子:name
成员方法:如果子类对父类的成员方法进行了重写,虚方法表中父类的方法就会被覆盖
2、弊端
不能调用子类的特有功能(父类中没有的方法):因为编译的时候会先检查左边的父类中没有该方法,如果没有直接报错。
解决方案:变回子类型,强制类型转换
例如:Animal a=new Dog()
a.lookHome()
强制类型转换:
Dog d=(Dog) a
a.looHome()
Cat d=(Cat) a
3、instanceof:判断类型
普通版:
变量名 instanceof 类名:如果是该变量是该类型,结果是true;如果不是,结果是false
升级版:
变量名1 instanceof 类名 变量名2:如果是变量1是该类型,则强转为该类型,并且重新命名为变量2,结果是true;如果不是,则不进行强转,结果是false
4、包 package
包名规则:公司域名反写+包的作用,全部英文小写 com.itheima.domain
使用同一个包中的类,不需要导包
使用java.lang包中的类的时候,不需要导包
其他情况都需要导包
同时使用两个包中的同名类,需要用全类名
5、final可修饰
1、方法:该方法是最终方法,不能被重写
2、类:该类是最终类,不能被继承
3、变量:叫做常量,只能被赋值一次,
常量命名规范:单个单词需全部大写;
多个单词需全部大写,单词之间用下划线隔开
4、若final修饰的变量是基本数据类型,那么变量存储的数据值是不变的
若final修饰的变量是引用类型,那么变量存储的地址值是不变的,对象内部可以改变
6、权限修饰符
private(自己用)<空着不写,默认(只能本包使用)<protected(受保护的,同一个类+不同包的子类+同一个包下的其他类 可用)<public(公共的)
7、代码块
1、局部代码块:在方法内的代码块,加大括号,提前结束变量的生命周期,变量只在所属的大括号内有效
2、构造代码块:写在成员位置,将构造函数中的公共部分提取出来,放入大括号中;创建本类的对象时,先执行构造代码块再执行构造方法
3、静态代码块:static{},随着类的加载而加载,自动触发,只执行一次
在类加载的时候,可以做一些数据初始化
8、抽象类和抽象方法
1、抽象方法:将共性的方法抽取到父类时,每一个子类执行的方法是不同的,因此需要在子类中重写该方法,在父类中不能确定该方法的具体内容,该方法可以定义为抽象方法;
2、抽象类:如果一个类中有抽象方法,该类必须声明为抽象类
定义格式:public abstract 返回值类型 函数名(参数列表);
public abstract class 类名{}
注意事项:1、抽象类不能创建对象
2、抽象类中不一定有抽象方法,有抽象方法的一定是抽象类
3、有构造方法:该方法的作用是当创建子类对象时,给属性进行赋值的
4、抽象类的子类:要么重写所有的抽象方法,要么该类是抽象类
9、接口:对行为的抽象
public **interface** 接口名{}
接口不能实例化
public class 类名 **implements** 接口名{}
接口的实现类:要么实现接口的所有方法,要么抽象类
一个类可以实现多个接口:
public class 类名 implements 接口1 接口2 {}
public class 类名 extends 类名 implements 接口1 接口2 {}
成员变量:只能是常量,默认修饰符为public static final
构造方法:没有
成员方法:只能是抽象方法,默认修饰符为public abstract
接口与接口之间的关系:可以单继承,也可以多继承,类实现最后一个接口时,必须实现子接口和父接口中的所有抽象类
JDK8开始接口中新增的方法:
JDK7前,接口中只能定义抽象方法
JDK8添加的方法:接口中可以定义有方法体的方法
1、默认方法(必须使用default修饰)
默认方法:public default 返回值类型 方法名(参数列表){}
默认方法不是抽象方法,不会被强制重写,但若要重写,需要去掉default
如果实现了多个接口,多个接口中存在相同名字的默认方法,那么子类就必须重写该方法
2、静态方法(必须使用static修饰)
public static 返回值类型 方法名(参数列表){}
静态方法只能通过接口名调用,不能通过实现类名和对象名调用
静态方法不能被重写
JDK9添加的方法:接口中可以定义私有方法,该方法只为这个接口使用,不被其他的类使用
给默认方法服务:private 返回值类型 方法(){}
给静态方法服务:private static 返回值类型 方法(){}
当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称为接口多态
10、适配器设计模式:解决接口和接口实现类之间的矛盾问题
设计模式就是解决各种问题的套路
当一个接口中抽象方法比较多的时候,但我只要使用其中一个方法的时候,可以使用适配器模式
实现方法:1、编写中间类XXXAdapter实现接口
2、对接口中的抽象方法进行空实现
3、让真正的实现类继承中间类,并重写需要用的方法
4、为了防止其他类创建适配器类的对象,要用abstract修饰适配器类
public interface inter{
public void method1(){}
public void method2(){}
public void method3(){}
public void method4(){}
public void method5(){}
public void method6(){}
public void method7(){}
}
适配器:
public abstract class interAdapter implements inter{
public void method1(){}
public void method2(){}
public void method3(){}
public void method4(){}
public void method5(){}
public void method6(){}
public void method7(){}
}
public class interImpl extends interAdapter{
public void method5(){
system.out.println("具体实现method5");
}
}
11、内部类
分为4种:成员内部类,静态内部类,局部内部类,匿名内部类
在一个类的内部定义一个类,称为内部类;
内部类表示的事物是外部类的一部分;
内部类单独出现没有意义;
public class car{
String carName;
String carColor;
int carAge;
class engine{
String engineName;
int engineAge;
}
}
内部类访问特点:
1、内部类可以直接访问外部类的成员,包括私有
2、外部类要访问内部类,必须创建内部类的对象
public class outer{
private int num=10;
class inner{
private int num=20;
public void show(){
int num=30;
sout(num);
sout(this.num);
sout(outer.this.num);
}
}
public inner getIntance{
return new inner();
}
}
创建成员内部类的对象:
1、直接创建:outer.inner oi=new outer().new inner();
2、若成员内部类是private,外界要访问成员内部类,需要在外部类创建方法,向外界提供内部类的对象
3、JDK16之前不可以在内部类里面定义静态变量,JDK16之前可以在内部类里面定义静态变量
静态内部类
创建内部类对象的方法:外部类.内部类 对象名=new 外部类.内部类();
若要访问外部类的静态成员和静态方法,则外部类.内部类.方法名;
若要访问外部类的非静态成员和方法,则需要提前创建对象,用对象访问
局部内部类
1、将内部类定义在方法里面
2、外界无法直接使用,需要在内部类里面创建对象
3、该类可以直接访问外部类的成员,也可以访问方法内的变量
匿名内部类:没有名字的类,可以写在成员位置,也可以写在局部位置
new 类名或者接口名(){
重写接口中的所有方法;
};
包含继承或实现,方法重写,创建对象
整体就是一个类的子类对象或者接口的实现类对象
当方法的参数是接口或者类时,可以使用匿名内部类的对象作为参数传递