抽象类的定义与使用
抽象类的概念:
抽象类就是在普通类的基础上扩充一些抽象方法,所谓的抽象方法指的是值声明而未实现的方法(没有方法体)
所有的抽象方法要求使用abstract关键字来定义,并且抽象等待所在的类也一定要用abstract关键字定义,表示抽象类
abstract class Person{//定义一个抽象类
private String name;//属性
public String getName() {//普通方法
return name;
}
public void setName(String name) {
this.name = name;
}
//{}里面的代码为方法体,所有抽象方法不包含方法体
public abstract void getPerson();//抽象方法
}
抽象类中包含抽象方法,而抽象方法不包含方法体,即没有具体实现因此抽象类不能够产生实例化对象
对于抽象类的使用原则
a.所有的抽象类必须有子类
b.抽象类的子类必须覆写抽象类的所有抽象方法
c.抽象类的对象可以通过对象多态性利用子类为其实例化
d.private 与 abstract 不能同时使用
abstract class Person{
private String name;//属性
public String getName() {//普通方法
return name;
}
public void setName(String name) {
this.name = name;
}
//{}里面的代码为方法体,所有抽象方法不包含方法体
public abstract void getPerson();//抽象方法
}
class Student extends Person{
@Override
public void getPerson() {//覆写父类方法
System.out.println("我是子类覆写后的对象");
}
}
public class Test{
public static void main(String[] args){
Person per = new Student();
per.getPerson();//调用子类覆写的方法
}
}
抽象类的相关规定:
1、在抽象类中允许提供构造方法,并且子类遵循对象实例化对象。实例化子类时必须先调用父类构造方法
abstract class Person{
private String name;//属性
public Person(){//构造方法
System.out.println("Person类的构造方法");
}
public String getName() {//普通方法
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void getInfo();//抽象方法
}
class Student extends Person{
public Student() {
super();//如果父类没有无参构造必须super指出调用的具体父类构造方法
System.out.println("Student类的构造方法");
}
@Override
public void getInfo() { }//子类覆写方法空实现
}
public class Test{
public static void main(String[] args){
new Student();//Person类的构造方法
// Student类的构造方法
}
}
对象实例化操作的核心步骤:
类加载 -> 类对象的开辟 -> 类对象属性的初始化(构造方法)
2、抽象类中允许不定义抽象方法,但是此时抽象方法仍然无法直接创建实例化对象
abstract class Person{
public void print(){
System.out.println("Person类的普通方法");
}
}
public class Test{
public static void main(String[] args){
Person per = new Person();//会报错,Person类是抽象的,无法实例化
}
}
3、抽象类一定不能使用final声明,因为final声明的类不允许有子类,抽象类又必须有子类;抽象方法也不能用private定义,因为抽象方法必须被覆写
4、抽象类分为内部抽象类和外部抽象类。内部抽象类中可以使用static定义来描述外部抽象类
abstract class Person{
public abstract void print();//外部类抽象方法
static abstract class Student{
public abstract void print2();//内部类抽象方法
}
}
class Child extends Person{
@Override
public void print() {
}
class A extends Student{
@Override
public void print2() {
}
}
}
接口的定义与使用
抽象类与普通类相比最大的特点就是约定了子类的实现要求,但是抽象类存在单继承局限,如果要约定子类的实现要求且避免单继承就可以使用接口
接口的基本概念
定义:接口就是一个抽象方法和全局常量的集合,用interface关键字定义
interface Imes{
public static final String MSG = "这是一个全局常量";
public abstract void print();//抽象方法
}
子类要想实现接口,就必须使用implements关键字来实现接口。
同时,一个子类可以实现多个接口,对于接口的子类必须覆写接口的全部抽象方法,随后利用子类的向上转型通过实例化子类得到接口的实例化对象
子类实现接口 & 父接口相互转换
interface Imes{
public static final String MSG = "这是一个全局常量";
public abstract void print();//抽象方法
}
interface INew{
public abstract String getNews();
}
class Mess implements Imes,INew {
@Override
public void print() {
System.out.println(Imes.MSG);
}
@Override
public String getNews() {
return Imes.MSG;
}
}
public class Test{
public static void main(String[] args){
Imes m = new Mess();//子类实现向上转型
//真正new的子类才有意义
m.print();//调用被子类覆写过的方法
INew n = (INew) m;
System.out.println(n.getNews());
}
}
接口使用限制
接口只允许使用public权限(不管是属性还是方法,其权限都是public)
接口的两种定义:
//完整格式:
interface Imes{
public static final String MSG = "这是一个全局常量";
public abstract void print();
}
//简化格式:
interface Imes{
final String MSG = "这是一个全局常量";
void print();
}
阿里编码规约:接口中的方法和属性不加任何修饰符号,public也不要加,保持代码的简洁性
当一个子类即需要实现接口又需要继承类时,需先使用extends继承一个抽象类,而后使用implements实现多个接口
//子类继承抽象类和实现接口
abstract class News{
//抽象类中方法前面的abstract不能省略,否则就是普通方法
public abstract void getNews();
}
class Message extends News implements Imes{
@Override
public void print() {
System.out.println("我覆写了接口方法");
}
@Override
public void getNews() {
System.out.println("我覆写了抽象方法");
}
}
public class Test{
public static void main(String[] args){
//Message是抽象类与接口的共同子类
Imes m = new Message();
m.print();
News news = (News) m;
news.getNews();
}
}
一个抽象类可以使用implements实现多个接口
interface Imes{
void print();
}
abstract class News implements Imes{
//抽象类中方法前面的abstract不能省略,否则就是普通方法
public abstract void getNews();
}
class Message extends News{
@Override
public void print() {
System.out.println("我实现了接口方法");
}
@Override
public void getNews() {
System.out.println("我实现了抽象方法");
}
}
此关系属于三层继承
class Message extends News implements Imes
一个接口可以使用extends继承多个父接口
interface A{
void printA();
}
interface B{
void printB();
}
interface C extends A,B{
void printC();
}
class Impl implements C{
@Override
public void printA() { }
@Override
public void printB() { }
@Override
public void printC() { }
}
接口可以定义一系列的内部结构,包括:内部普通类、内部接口。其中使用static定义的内部接口就相当于一个外部接口
//使用static定义的内部接口
interface A{
void printA();
static interface B{
void printB();
}
}
class Impl implements A.B {
@Override
public void printB() { }
}
接口能力的应用:定义标准
接口在实际开发中有三大核心应用环境
a.定义操作标准
b.表示能力
c.在分布式开发之中暴露远程服务方法