Java学习——blog 4

目录

接口与实现

接口

实现接口

接口回调

理解接口

接口的多态

接口参数

abstract类与接口的比较

1. 成员区别

2.关系区别

3.设计理念区别

面对接口编程

内部类与异常类

内部类

匿名类

异常类

异常问题

异常处理机制

异常的声明

断言

知识点小结

参考


接口与实现

  • 接口

为了克服Java单继承的缺点,Java使用了接口,一个类可以实现多个接口。使用关键字interface来定义一个接口。接口的定义和类的定义很相似,分为接口的声明和接口体。

a.接口的声明格式:

interface 接口的名字 {}

b.接口体:包含常量的声明和抽象方法两部分。常量的要求public、static(允许省略public、final、static修饰符)。抽象方法的要求public(允许省略public abstract修饰符)。​

例:

 interface A { public static final int MAX = 100; public abstract void setA(int a);}

​ 等价写法:

​ interface A { int MAX = 100; public void add();}

 ① 用interface来定义一个接口

​ ② 接口体中只有抽象方法且访问权限为public(允许省略public和abstract修饰符)。

​ ③ 接口体中常量的访问权限为public,而且是static常量(允许省略public、final和static修饰符)

​ ④ 可直接使用(接口名.常量)访问接口中的常量。

//例1
interface Printable{ 
public final static int Max=100;  //等价写法: int Max=100;
public abstract void add();  //等价写法: void add();
public absract float sum(float x,float y);  //等价写法: float sum(float x,float y);
}

//例2
interface AnimalTrain{
    public abstract void jump();
}
  • 实现接口

类实现接口用implements表示:class 类名 implements 接口名 { }             

//        public class B implements A{ int a; public void setA(int a){this.a = a;} }

​ ① 一个类需要在类声明中用关键字implements声明该类实现一个或多个接口,接口之间用逗号隔开。

​ ② 如果一个非抽象类实现了某个接口,那这个类必须重写这个接口中的所有方法,而且方法的访问权限一定要显示的用public来修饰,否则会降低访问权限。

​ ③抽象类可以重写接口中的方法,也可以直接拥有接口中的方法。

(1)public接口可以被任何一个类实现,而不加public修饰的友好类只能被同一个包的类实现。

(2)接口属于引用型变量,在接口中可以存放实现该接口的类的实例的引用,即存放对象的引用。

//抽象类实现接口
abstract class Dog implements AnimalTrain {  
}
//具体类实现接口
class Pig implements AnimalTrain {
    public void jump() {
        System.out .println("猪可以上树了");
    }    
}
class InterfaceDome {
    public static void main(String[] args) {
        //AnimalTrain是抽象的,无法实例化
        //AnimalTrain at=new AnimalTrain();
        //at.jump();
        AnimalTrain at=new Pig();
        at.jump();
    }
}
  • 接口回调

​ 可以把实现某一接口的类创建的对象的引用赋值给给接口声明的接口变量,那么该接口变量就可以调用被类实现的接口方法。实际上,当接口变量调用被类实现的接口方法时,就是通知相应的对象调用这个方法,这个调用的过程称为接口的回调。(类似上转型对象调用子类重写的方法)

​ A a; B b = new B(); a = b;

/*接口回调例子*/
interface ShowMessage{
	void 显示商标(String s);
}
class TV implements ShowMessage{
	public void 显示商标(String s) {
		System.out.println(s);
	}	
}
class PC implements ShowMessage{
	public void 显示商标(String s) {
		System.out.println(s);
	}
}
public class Example6_3 {

	public static void main(String[] args) {
		ShowMessage sm;    //声明接口变量
		sm=new TV();      //接口变量中存放对象的引用
		sm.显示商标("长城牌电视机");//接口变量调用被类实现的接口中的方法
		sm=new PC();      //接口变量中存放对象的引用
		sm.显示商标("联想奔月5008PC机");//接口回调
	}
}

/*运行结果*/
//长城牌电视机
//联想奔月5008PC机

  • 理解接口

(1)接口可以抽象出重要的行为标准,该标准用抽象方法表示。

(2)可以把实现接口的类的对象的引用赋值给接口变量,该接口变量可以调用被该类实现的接口方法。

  • 接口的多态

不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。

接口不能实例化,于是接口按照多态的方式来实例化。

  • 具体类多态(几乎没有)
  • 抽象类多态(常用)
  • 接口多态(最常用)
  • 接口参数

如果一个方法的参数是接口类型,我们就可以将任何实现该接口的类的实例的引用传递给该接口参数,那么接口参数就可以回调类实现的接口方法。

interface SpeakHello {
    void speakHello();
}
class Chinese implements SpeakHello {
   public  void speakHello() {
       System.out.println("中国人习惯问候语:你好,吃饭了吗? ");
   }
}
class English implements SpeakHello {
    public  void speakHello() {
       System.out.println("英国人习惯问候语:你好,天气不错 ");
    }
}
class KindHello {
   public void lookHello(SpeakHello hello) { //接口类型参数
       hello.speakHello();                    //接口回调
   }
}
public class Example6_5 {
   public static void main(String args[]) {
       KindHello kindHello=new KindHello();
       kindHello.lookHello(new Chinese());
       kindHello.lookHello(new English());
   }
}

  • abstract类与接口的比较

1. 成员区别

  • 抽象类:

可以变量,也可以常量

构造方法:有

成员方法:可以抽象,也可以非抽象

  • 接口:

成员变量:只可以常量,而且是静态的(默认修饰符:public static final )

成员方法:只可以抽象(默认修饰符:public abstract)

Tips:接口没有构造方法,因为接口主要是扩展功能的,而没有具体存在

/*所有类都继承object,类Object是类层次结构的根类,每个类都使用Object作为超类(默认格式:class Dog extends Object {})*/

2.关系区别

  • 类与类:

继承关系,只能单继承,可以多层继承。

  • 类与接口:

实现关系,可以单实现,也可以多实现,并且还可以在继承一个类的同时实现多个接口。

  • 接口与接口:

继承关系,可以单继承,也可以多继承。


interface Father{
public abstract void show();
}
interface Mother{
    public abstract void show2();
}
interface Sister  extends Father,Mother{     //接口间的继承关系可以单继承,也可以多继承
}
//class Son implements Father,Mother
class Son  extends Object implements Father,Mother{
    public  void show(){
        System.out.println("show son");
    }
    public  void show2(){
        System.out.println("show2 son");//可以单实现,也可以多实现
    }
}
class InterfaceDemo3{
    public static void main(String[] args) {
        //创建对象
        Father f=new Son();
        f.show();
        Mother m=new Son();
        m.show2();
    }
}

3.设计理念区别

  • 抽象类:

被继承体现的是:“is a”的关系,抽象类中定义的是该继承体系的共性功能。

  • 接口:

被体现的是:“like a”的关系,接口中定义的是该继承体系的扩展功能。

简言之:

① 抽象类与接口都是作为行为标准。

② 抽象类用在同一类别对象。

③ 接口更注重行为一致性。

④ 抽象类既可以有抽象方法也可以有非抽象方法,既可以有常量也可以有变量;而接口只可以有抽象方法和常量。

  • 面对接口编程

面向接口去设计程序,可以通过在接口中声明若干个abstract方法,表明这些方法的重要性,方法体的内容细节由实现接口的类去完成。
使用接口进行程序设计的核心思想是使用接口回调,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法。

利用接口也可以体现程序设计的“开-闭原则”,即对扩展开放,对修改关闭。

内部类与异常类

  • 内部类

Java支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类成为内部类的外嵌类。
        内部类与外部类区别
①内部类可以调用外部内的成员变量和方法
②内部类的类体中不可以声明类变量和类方法
③内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象

Tips:内部类的类体中不可以声明类变量和类方法。外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。

(1)声明内部类如同再类中声明方法或变量一样,一个类把内部类看作是自己的成员。

(2)外嵌类的类体中可以用内部类声明的对象,作为外嵌类的成员。

(3)外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。

(4)内部类的类体中不可以声明类变量和方法。

(5)外嵌类和内部类在编译时,生成两个.class文件。

  • 匿名类

(1)和子类有关的匿名类

直接使用一个类的子类的类体创建一个子类对象。

 ① 可以继承父类的方法也可以重写父类的方法

 ② 匿名类一定是内部类

 ③ 匿名类可以访问外嵌类的成员变量和方法,匿名类的类体中不可以声明static成员变量和方法。

 ④ 匿名类是子类,但没有类名,所以在用匿名类创建对象时直接用父类构造方法

  • 创建子类对象时,除了使用父类的构造方法外还有类体,此类体被认为是一个子类去掉类声明后的类体,称作匿名类。
  • 假设Bank是类,那么下列代码就是用Bank的一个子类(匿名类)创建对象 
new Bank () {        

    匿名类的类体

};

(2)和接口有关的匿名类

java允许直接用接口名和一个类体创建一个匿名对象。

  • 假设Computable是一个接口,那么,Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了Computable接口的类去掉类声明后的类体,称作匿名类。
  • 下列代码就是用实现了Computable接口的类(匿名类)创建对象:
 new Computable() {
 
    实现接口的匿名类的类体
         } ;

如果某个方法的参数是接口类型,那么可以使用接口名和类体组合创建一个匿名对象传递给方法的参数,类体必须重写接口的全部方法。

  • 异常类

异常问题

程序错误:
Error:Java虚拟机无法解决的严重问题,StackOverflowError和OOM
Exception:其它因编程错误或偶然的外在因素导致的一般性问题, 可以使
用针对性的代码进行处理。

  • 空指针访问
  • 试图读取不存在的文件
  • 网络连接中断
  • 数组角标越界

编译时异常  必须处置的异常
运行时异常java.lang.RuntimeException类及它的子类都是运行时异常。

异常处理机制

Java使用try~catch语句来处理异常,将可能出现的异常操作放在try~catch语句的try部分,将发生异常后的处理放在catch部分。

(1)try~catch语句的格式如下:

 try {

      包含可能发生异常的语句
}

 catch(ExceptionSubClass1 e) {
    …
}

 catch(ExceptionSubClass2 e) {
    …
} 

(2)带finally子语句的try~catch语句,语法格式如下:

 try{}

 catch(ExceptionSubClass e){ }

 finally{}

其执行机制是在执行try~catch语句后,执行finally子语句,也就是说,无论在try部分是否发生过异常,finally子语句都会被执行。

异常的声明

如果一个方法中的语句执行时可能生成某种异常, 但是并不能确定如何处理这
种异常, 则此方法应显示地声明抛出异常, 表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
在方法声明中用throws语句可以声明抛出异常的列表, throws后面的异常类型可以是方法中产生的异常类型, 也可以是它的父类。

1)一个方法不处理它产生的异常,而是沿着调用层次向上传递,由调用它的方法来处理这些异常,叫声明异常。

2)声明异常的方法:

在产生异常的方法名后面加上要抛出(throws)的异常的列表;

 手动抛出异常 用户自定义异常,throws关键字声明要产生的若干个异常。

如:

void compute(int x) throws ArithmeticException

      {//这里有异常发生,但是并没有处理…}
/* 自定义异常 */
public class ThisRuntimeException extends RuntimeException{

	public ThisRuntimeException() {
		super();
		// TODO Auto-generated constructor stub
	}
	public ThisRuntimeException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}
}

  • 断言

断言语句用于调试代码阶段。在调试代码阶段让断言语句发挥作用,这样就可以发现一些致命的错误,当程序正式运行时就可以关闭断言语句,但仍把断言语句保留在源代码中,如果以后应用程又需要调试,可以重新启用断言语句。

格式:
assert booleanException
assert booleanException;messageException

启动和关闭:
默认关闭,调试程序时用-ea开启
java -ea mainClasss

知识点小结

  • 一个源文件中既可以定义接口(interface),也可以定义类(class)
  • 使用关键字interface定义接口
  • 接口可以理解为一种特殊的类,里面全部是由全局常量公共的抽象方法所组成
  • 接口中只有常量,没有变量
  • 接口中只能有abstract方法,不能有非abstract方法(JDK7版本)
  • 接口中可以有abstract方法default修饰的带方法体的方法(JDK8版本)
  • 使得接口可以存在具体的方法,前提是方法需要被default或static关键字所修饰
  • 不可以用final、protected修饰接口以及接口中的方法
  • 能用public修饰接口,接口中的方法的访问权限一定都是public(允许省略public)
  • 接口中的方法不可以用private、protected修饰,可以用abstract修饰接口
  • 接口中 void f();方法声明等价于public abstract void f();即方法默认是public访问权限的abstract方法
  • 接口中 int x =10等价于 public static final int x = 10,即默认是常量
  • 一个接口可以有多个父接口(即继承多个接口),例如:interface A extends Com1,Com2
  • 类使用关键字implements 实现一个或多个接口,类声明class A implements B,C意思是A类实现B和C两个接口
  • 类声明class A extends B implements C 意思是A类是B类的子类,同时实现C接口
  • 一个类不能重复实现同一个接口,例如class A implements B,B
  • inferfce A extends B 意思是A是B的子接口
  • public接口可以被任何一个类实现
  • final类可以实现接口(final是类,类可以实现接口)
  • public类并不可以实现任何友好接口
  • 如果一个类和友好接口在同一个包里,就允许它实现该接口
  • 如果一个非abstract类实现某个接口,该类必须重写全部abstract方法
  • 一个类声明实现一个接口,但没有重写接口中的所有方法,那么这个类必须是抽象类,也就是说抽象类既可以重写接口中的方法也可以直接拥有接口中的方法
  • 子接口将继承父接口中的全部方法和常量
  • 可以用接口名直接访问接口中的常量
  • 接口也是Java中一种重要数据类型,用接口声明的变量称做接口变量
  • 接口变量中可以存放实现该接口的类的实例的引用(对象的引用)
  • 实现某一接口的类创建的对象的引用赋值给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口方法
  • 接口中只可以有常量,不能有变量。abstract类中既可以有常量也可以有变量
  • 【 abstract类中既可以有常量也可以有变量】
  • 接口中的常量必须指定初值
  • 类和它所实现的接口不一定在同一个包里

参考

JAVA第六章 接口与实现_FIRE-CSDN博客

Java 2 实用教程 第二、四、五、六章总结_Babybybybybyby的博客-CSDN博客_java2实用教程

https://blog.csdn.net/weixin_38235865/article/details/104533891

猜你喜欢

转载自blog.csdn.net/K_savo/article/details/122742932
今日推荐