一、抽象类
1.什么是抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对 象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类用来描述一种类型应该具备的基本特征与功能, 具体如何去完成这些行为由子类通过方法重写来完成,如:宠物类中,各种宠物都会吃东西,但由于吃的东西不同,猫吃鱼,狗吃骨头,所以吃东西这个细节并不相同,我们就让其子类具体实现。
特点: 抽象类不能被实例化(不能创建对象)
功能:用来进行类型隐藏和充当全局变量。
关键字: abstract 修饰类作为一个抽象类;
注意:可以有静态属性和静态方法,通过抽象类直接调用
1.1 抽象方法
当关键字abstract修饰一个方法,该方法是抽象方法。
- 抽象方法没有方法体
- 当抽象类中有抽象方法时,子类必须重写该方法,除非子类也是抽象类
- 抽象类可以有一般方法,但非抽象类不能有抽象方法
2.语法
- 在抽象类中,定义常量采用static + final
- 如果当前类中包含抽象方法,则当前类必须为抽象类
- 抽象类中的抽象方法可以使用public或protected,但不能使用private
/*
* 抽象类使用abstract关键字定义
* 2.如果当前类中包含抽象方法,则当前类必须为抽象类
*/
public abstract class Demo {
// 定义常量采用static + final
private static final String TYPE = "xxxx";
/*
* 抽象方法使用abstract关键字定义,没有方法体
*/
public abstract void dosth1();
// 抽象类中的抽象方法可以使用public或protected,但不能使用private
protected abstract void dosth2();
// 抽象类中允许存在普通实例方法
public void dosth3() {
}
}
/*
* 3.子类继承抽象类,必须“重写”父类中的抽象方法;
* 除非子类也是抽象类
*/
class DemoSon extends Demo{
@Override
public void dosth1() {
System.out.println("子类DemoSon重写父类的抽象方法");
}
@Override
protected void dosth2() {
}
}
public class Test01 {
public static void main(String[] args) {
// 1.抽象类不能被实例化(不能创建对象)
Demo demox = new DemoSon();
//demox.dosth();
}
}
二、final关键字
-
当用final修饰一个类时,表明这个类不能被继承。也就是 说,如果一个类你永远不会让他被继承,就可以用final进行修饰;
注意:作为修饰符时,final 不能和 abstract 同时出现。
public final class Cat { }
-
修饰成员变量: final成员变量表示常量,只能被赋值一次,赋值后值不再改变。 final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,
一种是在变量声明的时候初始化;
第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。 -
修饰普通变量 :当final修饰一个基本数据类型时,表示该基本数据类型的值一 旦在初始化后便不能发生变化;
如果final修饰一个引用类型时,则在对其初始化之后便不能再 让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化 的。 -
修饰方法参数: 若某个参数被final修饰了,则代表了该参数是不可改变的。
public class Test01 {
public static void main(String[] args) {
// final关键字修饰基本类型时,不允许该变量重新赋值
final int aaa = 23;
// 不允许重新赋值
// aaa = 2350;
// final关键字修饰引用类型时,不允许该引用重新指向新的对象
final User user = new User();
// 不允许引用user指向新的对象
// user = new User();
// user = new User();
// user = new User();
dosth("孙悟空");
}
// 方法参数的类型前使用final,代表该参数只能用于接收参数值,但不能修改
public static void dosth(final String param) {
System.out.println(param);
// 不能修改final参数
// param = "猪八戒";
System.out.println(param);
}
}
- 修饰方法 :使用final方法的原因有两个: 第一个原因是把方法锁定,以防任何继承类修改它的含义;
第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。
public class Cat {
// final 关键字修饰成员方法
public final void getName( ) { }
}
- final 修饰的方法不能被 重写;
- 父类的final方法是不能被子类所 覆盖 的,也就是说子类是不能够存在和父类一模一样的方法的;
- final 修饰的方法可以被 重载,且重载方法可以 不是 final 修饰。
三、接口
1.定义
接口是一种约束形式,其中只包括成员定义, 不包含成员实现的内容;
2.定义接口的目的
为不相关的类提供通用的处理服务
3.语法
interface
- 使用 interface 代替 class 修饰类名,定义一个接口;
- 接口不能被实例化
- 接口没有构造方法
- 接口中允许定义抽象方法(可以省略abstract关键字),必须使用public修饰符,实现类必须重写抽象方法
- 从JDK8开始,接口中允许定义default默认方法(实例方法),实现类可以选择“重写”或者“不重写”
- 接口中定义常量,无需static + final关键字
- 实现类实现接口采用implements关键字,可以一次性实现多个接口
public interface MyInterface {
// 接口中定义常量,无需static + final
String TYPE = "xxxxx";
// 接口中可以定义抽象方法(省略abstract关键字)
public void dosth1();
// 接口中定义的抽象方法,必须使用public修饰
// protected void dosth2(); //错误
// 如果省略public,默认为public
void dosth3();
// 接口中不允许出现普通的实例方法
// 错误
//public void dosth4() {
//
//}
// 从JDK8开始,允许出现default定义的默认方法
public default void dosth5() {
// 对于默认方法,实现类可以选择"重写"或者"不重写"
}
}
implements
使用 implements 实现接口,实现接口需要重写接口的全部方法;
使用 implements 实现接口时,允许实现多个接口, 多个接口间用 “,” 分割;(注意:实现多个接口时,需要同时实现多个接口的方法。)
public interface MyAble {
public void dox();
}
public class Test01 {
public static void main(String[] args) {
// 接口定义的引用my,不能被实例化(与抽象类特点一致)
// MyInterface my = new MyInterface();
// MyInterface.TYPE = "ZZZZZZ";
}
}
/*
* 类 “implements实现 ” 一个接口
* 该类被称为“实现类”
*/
class MyInterfaceImpl implements MyInterface,MyAble{
@Override
public void dosth1() {
}
@Override
public void dosth3() {
}
@Override
public void dox() {
}
}