抽象类
抽象类的来源:
封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为
继承:将子类共有的部分提取出来,定义一个父类,子类继承父类
弊端:子类中的方法都需要重写时,但是可能忘记或故意不重写
这时候就需要抽象方法:
当你定义了一个抽象方法,子类必须重写这个方法,否则就会报错
抽象方法所在的类就称为抽象类
抽象方法:
将共性的行为抽取到父类之后,由于每个子类执行的内容是不同的,所以,在父类中不能确定具体的方法体,该方法就可以定义为抽象方法。
如何定义?
一、抽象方法:
public abstract 返回值类型 方法名(参数列表);
二、抽象类:
public abstract class 类名{}
注意事项:
一、抽象类不能实例化(创建对象)
二、抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
三、抽象类可以有构造方法
四、抽象类的子类:
要么重写抽象类中的所有抽象方法
要么是抽象类
抽象类和抽象方法的意义:
在团队开发中统一开发思路,每个子类都要强制重写这个方法
值得注意的是:抽象类不能被实例化
接口
假如一个方法不被所有子类共有,但又被部分子类共有,为了这个功能易于维护和统一性,我们会新定义一个拥有该功能的接口,接口可以理解为一种规则,不是一种继承体系,是对行为的抽象.
如何定义一个接口
public interface 接口名{}
接口不能实例化
接口和类是实现关系,通过implements关键字表示
public class 类名 implements 接口名{}
接口的子类(实现类)
要么重写接口中的所有抽象方法
要么是抽象类
接口中成员的特点:
成员变量:
只能是常量
默认修饰符:public static final
构造方法:
无
成员方法:
只能是抽象方法
默认修饰符:public abstract
JDK7以前:接口中只能定义抽象方法
JDK8的新特性:接口中可以定义有方法体的方法 (为了接口升级的时候使用)
JDK9的新特性:接口中可以定义私有方法
新增默认方法:默认方法可以通过接口的实现对象直接调用,可以被接口的实现类重写
接口和类之间的关系:
类和接口的关系:
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
接口和接口的关系
继承关系,可以单继承,也可以多继承
*
*扩展:
-
接口中的默认方法是抽象方法,public和abstract可以省略,而default不能省
-
如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
-
JDK8之后新增静态方法:
-
静态方法只能通关接口名调用,不能通关实现类名或者对象名调用,同时静态方法不能被重写 (s.eat();会出错)
-
#### 静态方法不会被添加到虚方法表,当子类中出现同名方法时,只会调用子类中的方法
-
-
JDK9之后新增私有方法:
-
私有方法:private void show(){}给默认方法服务
-
静态私有方法:private static void show(){}给静态方法服务
接口的应用:
-
可以将多个类使用到的功能定义为接口,是各种各样行为的规则
-
当我在调用方法时使用了接口,我就可以传递这个接口所有的实现类对象
-
public void 搬家(运输的接口 c){} (意思是:实现了这个接口的类的对象都能写进参数,
-
#### 比如车和人都能使用运输接口,那车和人就都可以写进参数)
适配器设计模式:
-
-
设计模式(Design Pattern)是一套被反复使用,多数人知晓的、经过分类编目、代码设计经验的总结
-
#### 使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性,程序的重用性。
-
(设计模式就是各种套路)
*
-
-
比如在某个接口中实现了十个方法,但是我们的类中只需要使用一个方法,那可以创建中间类,
-
然后在中间类中重写所有的方法(空方法),然后用我们的类去继承这个中间类,这样就只需要重写需要的方法了
-
一般情况下适配器对象会被设计为abstract抽象类,目的是为了防止外界创建它的对象(无意义)
-
-
当一个方法中抽象方法过多,但是我们只需要其中一部分的时候,就可以使用适配器设计模式:中间类XXXXAdapter,实现对应接口
内部类
什么是内部类:
类的五大成员:
属性,方法,构造方法,代码块,内部类
内部类就是在类的内部再定义一个类,如:
public class Outer{
methods1;
public class Inner{
methods2;
}
}
与这两个类无关的类称为外部其他类
例:
需求:写一个javabean类描述汽车
属性:汽车的品牌,车龄,颜色,发动机的品牌,使用年限
如果定义一个car类,在car类中实现所有的属性,那么你要考虑到发动机实际上独立的个体
但是发动机是随着车出现的,不会独立存在,所以需要在car中再定义发动机类
内部类表示的事物应该是外部类的一部分
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
内部类的种类:
1. 成员内部类
2. 静态内部类
3. 局部内部类
4. 匿名内部类----需要重点掌握
(前面三种只需要了解)
成员内部类的注意事项:
1.写在成员位置的,属于外部类的成员
2.当用private修饰成员内部类之后在外界就不能直接创建内部类的对象,只能在外部类中创建
3.当protected修饰可以在同类,同包,或者不同包的子类中访问
4.当用public修饰,除了同类、包,或者不同包中的子类中,还可以在不同包的无关类中访问
5.static修饰时为静态内部类而不是成员内部类
6.在成员内部类里面,JDK16之前不能定义静态变量,JDK16之后才可以定义静态变量
成员内部类的对象:
方法一、在外部类中编写方法,对外提供内部类的对象。(当private修饰内部类时)
方法二、直接创建内部类的格式:外部类名.内部类名 对象民 = 外部类对象.内部类对象;
示例:Outer.Inner oi = new Outer().new Inner();
为什么:因为我们创建的是内部类的对象,但是单独存在无意义,所以需要添加一个外部类的标识
oi为变量名称,等号右边是对象的地址值,Inner类在Outer中,也需要new
简单来讲就是链式编程
静态内部类:
1.静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的则需要创建对象
2.创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
3.如果方法也是静态,那直接 外部类名.内部类名.方法名(); 就可以调用
局部内部类:
1.将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量
2.外界是无法直接使用的,需要在方法内部创建对象并使用
3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量
匿名内部类:
1.匿名内部类本质上就是隐藏了名字的内部类
new 类名或者接口名(){
重写方法;
};