java抽象类与接口,请阐述一下java类抽象类接口三者的区别

  java抽象类与接口,请阐述一下java类抽象类接口三者的区别

  

目录

1.抽象类和抽象方法2。相关面试问题1。抽象类一定要有抽象方法吗?2.普通类和抽象类有什么区别?3.抽象类可以用final修饰吗?3.3.1接口中的常量3.2接口中的方法3.2.1接口中的常用方法3.2.2接口中的静态方法3.2.3接口中的默认方法3.3接口中的接口和枚举类3.4接口和抽象类概述

 

  00-1010抽象方法和抽象类必须使用抽象修饰符来定义。有抽象方法的类只能定义为抽象类,抽象类中不能有抽象方法。抽象方法和抽象类的规则如下:

  (1) 类和抽象方法必须用抽象修饰符来修饰,抽象方法不能有方法体。

  (2) 抽象类不能被实例化。不能用new关键字调用抽象类的构造函数来创建抽象类的实例。即使抽象类不包含抽象方法,这个抽象类也不能创建实例。

  (3) 抽象类可以包含六个组件:字段、方法、构造函数、初始化块、内部类和枚举类。抽象类的构造函数不能用来创建实例,主要用来被它的子类调用。

  包含(4) 抽象方法的类只能定义为抽象类。

  (5) 抽象不能用于修改字段或局部变量,即没有抽象变量或抽象字段。抽象也不能用来修改构造函数。没有抽象构造函数,抽象类中定义的构造函数只能是普通构造函数。

  定义一个抽象方法,只需要给普通方法加上抽象修饰符,去掉普通方法的方法体(也就是方法后面的花括号),在方法后面加上分号。

  公共抽象类Person {//初始化块{System.out.println(执行Person类的初始化块);} private int age//这个构造函数不是创建对象,而是调用public person(){ } public person(intage){ This . age=age;}//抽象方法,没有方法体公共抽象void show();public void test(){ system . out . println(非抽象方法);}}抽象类不能用来创建实例,只能作为父类被其他子类继承。

  公共课学生延伸人{公共课学生(int age){ super(age);} @ override public void show(){ system . out . println( overriding abstract class中的抽象方法);} }注意:

  当(1) 用abstract来修饰一个类的时候,说明这个类只能被继承;当使用abstract来修饰一个方法时,表示这个方法必须由一个子类来实现(即覆盖)。最终修饰的类不能被继承,最终修饰的方法不能被重写。所以final和abstract永远不能同时使用。

  当(2) 用static来修饰一个方法的时候,说明这个方法是属于类本身的,也就是可以通过类来调用。但是如果将方法定义为抽象方法,那么通过类调用方法时会出错(调用没有方法体的方法肯定会出错)。所以静态和抽象不能同时修饰一个方法,也就是没有类抽象方法。

  (3) 抽象类不能创建实例,它只能作为父类继承。从语义上看,抽象类是从众多具体类中抽象出来的父类,它的抽象层次更高。

  

1. 抽象类和抽象方法

 

  00-1010抽象类不一定要有抽象方法。抽象类可以包含抽象方法和非抽象方法,或者只包含抽象方法。

  公共抽象类person { public void test(){ system . out . println(非抽象方法);}}

  00-1010 (1)普通类不能包含抽象方法,抽象类可以包含抽象方法。

  (2)抽象类不能直接实例化,只能作为父类被其他子类继承,普通类可以直接实例化。

  

public abstract class Person { // 抽象方法 public abstract void show(); // 非抽象方法 public void test(){ System.out.println("非抽象方法"); }}

外部类的形式继承抽象类Person

 

  

public class Student extends Person { @Override public void show() { System.out.println("重写抽象类中的抽象方法"); }}

内部类的形式继承抽象类Person

 

  

public class Teacher { public static void main(String[] args) { Person person = new Person() { @Override public void show() { System.out.println("重写抽象类的抽象方法"); } }; person.show(); }}

 

  

3、抽象类能使用 final 修饰吗?

当使用abstract修饰类时,表明这个类只能被继承;当使用abstract修饰方法时,表明这个方法必须由子类提供实现(即重写)。而final修饰的类不能被继承,final修饰的方法不能被重写。因此final和abstract永远不能同时使用。

 

  

 

  

3. 接口

接口只是对一类事物的属性和行为更高层次的抽象。对修改关闭,对扩展(不同的实现implements)开放,接口是对开闭原则的一种体现。

 

  接口体:

  

interface 接口名{ 常量 抽象方法 静态方法 默认方法}interface 接口名{ 常量 抽象方法 静态方法 默认方法}

 

  

3.1 接口中的常量

接口中的所有成员变量都默认是由public static final修饰的,且由于接口里没有构造器和初始化块,因此需要在定义Field时就指定初始值;

 

  接口中的Field都是常量,经常用来被定义常量的集合:

  

public interface FieldInterface { /** * 一年的天数 */ int DAY = 365; /** * 一年的星期数 */ int WEEK = 52; /** * 一年的月数 */ int MONTH = 12;}
public class Main { public static void main(String[] args) { /** * 接口中定义的Field都是public static final修饰的常量,因此需要使用接口名来访问 */ System.out.println(FieldInterface.DAY); }}

一个类实现某个接口时,该类将会获得接口中定义的Field :

 

  

public class FieldImpl implements FieldInterface { // 将会继承FieldInterface中定义的所有Field}
public class Main { public static void main(String[] args) { System.out.println(FieldInterface.DAY); // 使用实现类调用接口中的常量 System.out.println(FieldImpl.DAY); }}

 

  

3.2 接口中的方法

接口中的三种方法:

 

  (1) 接口中的普通方法,默认都是public abstract修饰的抽象方法,没有方法体;

  (2) 接口中的静态方法,静态方法必须要有实现,且这个静态方法只能用public修饰或不写;

  (3) 接口中的默认方法,默认方法必须要有实现,用default修饰且不可省略,用来供子类继承或重写,二选一,但只能在实现类中使用或者实现类对象中使用;

  分别展开举例说明:

  

 

  

3.2.1 接口中的普通方法

接口中的普通方法,默认都是public abstract修饰的抽象方法,没有方法体;

 

  接口的实现类如果是普通类,那么必须重写接口中的所有抽象方法接口的实现类如果是抽象类,那么可以不用重写接口中的抽象方法

public interface BaseMethod { /** * 接口中的普通方法 * 以下方法默认都是public abstract修饰的抽象方法,没有方法体 */ public abstract void show1(); abstract void show2(); public void show3(); void show4();}

① 接口的实现类如果是普通类,那么必须重写接口中的所有抽象方法:

 

  

public class BaseMethodImpl implements BaseMethod { /** * 当一个类实现BaseMethod接口后,需要实现BaseMethod接口中的所有抽象方法 */ @Override public void show1() { } @Override public void show2() { } @Override public void show3() { } @Override public void show4() { }}

② 接口的实现类如果是抽象类,那么可以不用重写接口中的抽象方法:

 

  

public abstract class BaseMethodImpl2 implements BaseMethod { /** * 抽象类会继承接口中定义的所有抽象方法和field * 这个类仍然是抽象类,可以不用实现接口中所有的抽象方法 */ @Override public void show1() { }}

 

  

3.2.2 接口中的静态方法

调用形式:接口名.静态方法名接口中定义的静态方法,不能被子接口继承接口中定义的静态方法,不能被实现该接口的类继承

public interface StaticMethod { /** * 接口中的静态方法 * 接口中是可以定义静态方法的,静态方法必须要有实现。且这个静态方法只能用public修饰或不写。 */ public static void test1(){ System.out.println("接口中定义静态方法"); }}
public class Main { public static void main(String[] args) { /** * 接口中的静态方法,只能通过接口名来调用,就像类的静态方法一样 */ StaticMethod.test1(); }}

① 接口中定义的静态方法不能被子接口继承:

 

  

public interface StaticMethod1 extends StaticMethod {}
public class Main { public static void main(String[] args) { /** * 编译报错,说明接口中定义的静态方法不能被子接口继承 */ StaticMethod1.test1(); }}

② 接口中定义的静态方法不能被实现类继承:

 

  

public class StaticMethodImpl implements StaticMethod {}
public class Main { public static void main(String[] args) { /** * 编译报错,说明接口中定义的静态方法不能被实现类继承 */ StaticMethodImpl.test1(); }}

 

  

3.2.3 接口中的默认方法

接口中的默认方法,不能通过接口名调用,需要通过接口实现类的实例进行访问,即对象名.默认方法名()接口中的默认方法,可以被实现类继承,也可以在实现类中重写接口中的默认方法,可以被子接口继承,也可以在子接口中重写

public interface DefaultMethod { /** * 接口中的默认方法 * 用default修饰,不可省略,供子类继承或重写,二选一,但只能在实现类中使用或者实现类对象中使用 */ public default void test2(){ System.out.println("接口中定义默认方法"); }}

① 接口中的默认方法,可以被实现类继承,也可以在实现类中重写

 

  

public class DefaultMethodImpl implements DefaultMethod { // 继承接口中的方法}
public class DefaultMethodImpl implements DefaultMethod { // 重写接口中的方法 @Override public void test2() { System.out.println("实现类重写接口中的方法"); }}
public class DefaultMethodImpl implements DefaultMethod { // 重写接口中的方法 @Override public void test2() { System.out.println("实现类重写接口中的方法"); }}

② 接口中的默认方法,可以被子接口继承,也可以在子接口中重写

 

  

public interface DefaultMethod1 extends DefaultMethod { // 继承父接口中的方法}
public interface DefaultMethod1 extends DefaultMethod { // 重写父接口中的方法 @Override default void test2() { System.out.println("子接口中重写父接口中的方法"); }}

 

  

3.3 接口中的接口和枚举类

public interface Base { /** * 在接口中定义接口 */ interface CommonConstant{ /** * 一年的天数 */ int DAY = 365; /** * 一年的星期数 */ int WEEK = 52; /** * 一年的月数 */ int MONTH = 12; /** * 在接口中定义静态方法 */ static void show() { System.out.println("在接口中定义接口"); } } /** * 在接口中定义枚举类 */ @AllArgsConstructor enum WhiteStatusEnum { /** * 未加白 */ NO_WHITE("未加白", "未加白"), /** * 部分加白 */ PART_WHITE("部分加白", "部分加白"), /** * 全部加白 */ ALL_WHITE("全部加白", "全部加白"); @Getter private final String label; @Getter private final String value; }}

 

  

3.4 接口和抽象类

共同点:

 

  (1) 接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承;

  (2) 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法;

  (3) 接口和抽象类中都可以包括抽象方法和非抽象方法;

  不同点:

  (1) 接口里只能定义静态常量Field,不能定义普通Field;抽象类里则既可以定义普通Field,也可以定义静态常量Field。

  (2) 接口里不包含构造器;抽象类里可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。

  (3) 接口里不能包含初始化块;但抽象类则完全可以包含初始化块。

  (4) 一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足。

  

public class MethodImpl implements FieldInterface, MethodInterface {}

 

  

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注盛行IT的更多内容!

 

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: