天天看点

Java抽象类与接口编程

抽象类

定义:用关键字abstract关键字类修饰的一个类,叫做抽象类。

abstract class  ClassName{
    
    }
           

注意:1、抽象类必须被继承。

2、抽象类不能直接实例化。它只能作为超类,这一点与最终类(final类)正好相反。

3、抽象类中可以有抽象方法与普通方法,但抽象方法必须在抽象类中。

抽象方法

定义:用abstract来修饰的一个方法,叫做抽象方法。

abstract class  ClassName{
    abstract returnType abstractMethod([paramlist]);
    }
           

注意:1、抽象方法必须被重写;

2、抽象方法在抽象类中只能声明,不能实现。即不能有{}。

3、定义抽象方法的类必须是抽象类。

4、子类继承抽象类时,必须重写所有的抽象方法子类才能成为普通类,不然子类也是抽象类。

例如:注意4例子

abstract class Animal{
 abstract void eat();
 abstract  void sleep();
}
abstract class Dog extends Animal{
 public void eat() {//抽象父类eat方法,但未重写sleep方法
  //所以子类Dog也是一个抽象类。
 }
// public void sleep() {
//  
// }
}
           

接口

定义:接口就是方法定义与常量的集合。 从语法上讲:接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的的定义,没有方法的实现(没有普通方法和普通变量)。

实现:用interface关键字实现。

[public] interface interfaceName [extends Super Interface1, SuperInterface2,…]{

}

public class InterfaceTest {
public static void main(String[] args) {
 student stu=new student();
 stu.sleep();
 System.out.println(stu.a);//输出接口person里面的常量
}
}
class student implements Agenf{//接口的使用,关键字implements
 public student() {
 }
 @Override
 public void eat() {
  System.out.println("吃饭!!");
 }
 @Override
 public void sleep() {
  System.out.println("睡觉!!!");
 }
}
interface person{
 int a=10;
 void eat();
}
interface Animal1{//声明接口
 int b=100;
 void sleep();
}
interface Agenf extends person,Animal1{//继承两个接口
 @Override
 default void sleep() {//按道理说这里是不可以实现方法的
 //因为接口里面应该只有方法的声明,不能有实现。
 //但这样也没有错,我也不知道为何!
 }
 @Override
 default void eat() {
 }
}
           

特点:1、与类的继承不同,一个接口可以继承多个父接口;

2、一个public接口只能定义在同名的.java文件中

接口的使用

1、用implements关键字来表示一个类的使用某个接口;

2、类可以使用接口定义的常量,但必须实现接口中定义的所有方法;

3、接口可以实现多重继承,即继承多个接口;

4、接口作用与抽象类相似,只定义原型,不直接定义方法内容;

5、接口中的方法和常量必须是public。

interface person{//其实是public interface peerson
 int a=10;//public static final int a=10; 
 //public static final 省略 
/* public abstract 省略 */ void eat();
}
           

JAVA8接口的新特性

java8允许我们给接口添加一个非抽象的方法实现,并且有方法体,只需使用关键字default或者static 即可,这个特征又叫扩展方法

//解释了上面代码里遗留的问题
interface Agenf{
 default void sleep() {//按道理说这里是不可以实现方法的
//但是Java8过后可以,扩展特性。
 }
 @Override
 default void eat() {
 }
}
           

注意事项(重写规则):

1、子类继承的多个接口中同时存在同名,同参数的静态方法。子类在调用父类的静态方法的时候,需要通过父类名.静态方法名。若该静态方法如果在子类中也定义,它是不算被重写的。

2、如果两个接口的方法名和参数相同都是default方法,里面的实体不同,在子类中需要重写。

3、如果两个接口中的方法名,参数都相同的方法,一个接口是抽象方法,一个是default修饰的方法体。在类中也必须被重写。

4、如果一个类实现了一个接口的默认方法,同时又继承了另外一个类的方法。那么子类的方法优先跟父类的方法行为一致。

抽象类与接口异同点

相同点:

1、都必须通过其他类才能实现;

2、不能直接实例化。

不同:

1、抽象类是类,可包含变量及抽象方法的定义;

2、接口实质不是类,只含有类常量以及抽象方法的定义;

3、类只能单一继承,接口可以多继承。

4、接口只能public修饰符,类可以是任意修饰符;

5、继承强调关系:is a 接口强调功能: has a

内部类

定义:定义在类内部的类称为内部类,可以直接访问外围类相关成员。

说明:内部类编译后也会形成一个单独的.class,但它附属于其包含类。

分类:类体中的内部类 和 方法体中的内部类

一、类体中的内部类:

相当于类体中的成员变量,可以在类的内部和外部使用。

命令格式: 外围类类名+$+内部类类名.class

静态内部类:static 修饰,只能访问外围类静态的成员。

实例内部类:可以访问外围类所有成员。

实例内部类:

public class TestInnerClass {
public static void main(String[] args) {
 Outer ou=new Outer();
 //创建内部类对象
 Outer.Inner inner=new Outer().new Inner();
 inner.show();
}
}
class Outer{
 private int age=10;//外部类成员变量
 public void testOuter() {
  System.out.println("这是外部类!");
 }
 class Inner{//普通内部类不能用static方法和属性
  private int age=20;//内部类成员变量
  public void show() {
   int age=30;//方法成员变量
   System.out.println("外部内的成员变量age:"+Outer.this.age);
   System.out.println("内部内的成员变量age:"+this.age);
   System.out.println("方法成员变量age:"+age);
  }
 }
}
           

静态内部类:

public class OuterTest2 {
public static void main(String[] args) {
 //静态内部类的创建
 Outer2.Inner2 inner2=new Outer2.Inner2();
}
}
class Outer2{
 static class Inner2{
 }
}
           

二、方法体中的内部类:只能在定义它的方法中或者代码块中使用,不能在外部使用。(又可以细分为有名字的内部类和匿名内部类)

命名格式:外围类名字+ + 数 字 + 内 部 类 类 名 . c l a s s 外 围 类 类 名 + + 数字+内部类类名.class 外围类类名+ +数字+内部类类名.class外围类类名++数字.class

匿名内部类:

public class TestInn {
 public static void test01(AA a) {
  System.out.println("---------");
  a.aa();
 }
 public static void main(String[] args) {
  TestInn.test01(new AA() {//匿名内部类,只能使用一次
   public void aa() {
    System.out.println("new AA(){}");
   }
  });
 }
}
interface AA{
 void aa();
}
           

注意:匿名内部类没有访问修饰符,没有构造方法。

三、何时使用内部类

1、当第一个类能直接访问另外一个类中的成员时,将一个类定义为另一个类的内部类。

2、用于处理在GUI部分的事件处理机制中。

好处:可以直接使用包含类的变量和方法。(内部类只能在包含它的类中使用,同时把它看作该包含类的一段特殊代码。)

继续阅读