Java小课堂 第八章 抽象类与接口(下)

发布于:2024-04-09 ⋅ 阅读:(45) ⋅ 点赞:(0)

8.5、模板方法设计模式【了解】

抽象类体现的就是一种模板方法设计模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

解决的问题:

当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。

换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。

abstract class Template {

public final void getTime() {

long start= System.currentTimeMillis();

code();

long end= System.currentTimeMillis();

System.out.println("执行时间是:"+ (end-start));

}

public abstract void code();

}

class SubTemplate extends Template {

public void code() {

for(inti= 0; i< 10000; i++) { System.out.println(i); }

  }

}

8.6 接口【重点】

8.6.1 什么是接口?

有时必须从几个类中抽象出一个父类,子类继承它所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。

有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/则必须能...”的思想。继承是一个"是不是"的关系,而接口实现则是"能不能"的关系。

接口的本质是契约,标准,规范,就像我们的法律一样,制定好后大家都要遵守。

8.6.2 接口的特点

接口(interface)是抽象方法和常量值定义的集合。接口的特点:

用interface来定义。

接口中的所有成员变量都默认是由public static final修饰的。

接口中的所有方法都默认是由public abstract修饰的。

接口中没有构造器。

接口采用多继承机制。

接口使用的注意事项:

定义Java类的语法格式:先写继承,后写实现;

class SubClass extends SuperClass implements InterfaceA{ }

一个类可以实现多个接口,接口也可以继承其它接口。

实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化,否则,仍为抽象类。

接口的主要用途就是被实现类实现。(面向接口编程)。

与继承关系类似,接口与实现类之间存在多态性。

接口和类是并列关系,或者可以理解为一种特殊的类。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义(JDK7.0及之前),而没有变量和方法的实现。

8.6.3 JDK8.0中关于接口的新特性【面试点】

Java8中,可以为接口添加静态方法和默认方法:

静态方法:可以通过接口直接调用静态方法,并执行其方法体。

默认方法:默认方法使用default关键字修饰,通过实现类的对象来调用。

接口方法的冲突解决:

如果多个接口中定义了同名同参数的默认方法,在实现类同时实现了这两个接口时,会出现接口冲突。可以通过在实现类里覆盖接口中同名同参数的默认方法来解决冲突。

如果一个接口中定义了一个默认方法,而父类中也定义了一个同名同参数的非抽象方法,则不会出现冲突问题。因为此时遵守:类优先原则,接口中具有相同名称和参数的默认方法会被忽略。

8.6.4 接口与抽象类的区别【面试点】

8.7内部类【难点】【面试点】

8.7.1 什么是内部类

在Java中,允许一个类定义另一个类,前者称为外部类,后者称为内部类。

Inner Class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。

Inner Class的名字不能与包含它的外部类名称相同;

内部类分类:

      • 成员内部类:非静态成员内部类、静态成员内部类;
      • 局部内部类:匿名内部类

8.7.2 成员内部类

成员内部类与外部类的不同点:

可以采用private或protected修饰符修饰;

可以在内部类中调用外部类的成员;

可以使用static关键字修饰,但此时就不能再使用外层类的非静态成员。

成员内部类的特点:

可以在内部定义属性、方法、构造器等成员;

可以直接使用外部类的所有成员,包括私有的数据;

外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式;

可以使用abstract关键字修饰,因此可以被其它的内部类继承;

可以使用final关键字修饰;

编译以后生成的字节码文件格式:OuterClass$InnerClass.class。

注意事项:

外部类或静态成员内部类中可以使用static关键字,而非静态成员内部类中不能使用static关键字;

外部类的静态成员部分使用内部类成员时,可以考虑使用静态内部类。

示例1:

class Outer {

private int s;

public class Inner {

public void inner_method() {

s= 100;

System.out.println("在内部类Inner中s="+ s);

}

}

public void outer_method() {

Inner i= newInner();

i.inner_method();

}

}

public class InnerTest {

public static void main(String args[]) {

Outer o= new Outer();

o.outer_method();

}

}

示例2:

public class Outer {

private int s= 111;

public class Inner {

private int s= 222;

public void inner_method(int s) {

System.out.println(s);     // 输出局部变量s

System.out.println(this.s);  // 输出内部类对象的属性s

System.out.println(Outer.this.s);   // 输出外部类对象属性s

}

}

public static void main(String args[]) {

Outer a= new Outer();

Outer.Inner b= a.new Inner();

b.mb(333);

}

}

8.7.3 局部内部类

局部内部类的特点:

局部内部类仍然是一个独立的类,在编译之后局部内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号,以及数字编号;

局部内部类只能在声明它的方法或代码块中使用,而且是先声明后使用,除此之外的任何地方都不能使用该类;

局部内部类可以使用外部类的成员,包括私有的;

局部内部类可以使用外部方法的局部变量,但是必须是final的,由局部内部类和局部变量的生命周期不同所致;

局部内部类和局部变量地位类似,不能使用访问修饰符修饰;

局部内部类不能使用static修饰,因此也不能包含静态成员。

匿名内部类及其特点:

匿名内部类不能定义任何静态成员、方法和类;

匿名内部类必须继承父类(一般为抽象类)或实现接口;

匿名内部类一定是在new的后面,用其隐含实现一个接口或类;

匿名内部类只能创建一个实例。

new 父类构造器(实参列表)| 实现接口 () {

//匿名内部类的类体部分

}

示例:

interface A {

public abstract void fun();

}

public class Outer {

public static void main(String[] args) {

new Outer().call_Inner_method(new A(){

@override

public void fun() {

System.out.println(“implement for fun");

}

});

}

public void call_Inner_method(A a) {

a.fun();

}

}  

8.8 小结

static关键字可以修饰属性、方法、代码块、内部类,一般用来修饰属性和方法。【难点】

final关键字可以修饰属性、方法、类,通常使用在属性上,用来声明常量。【重点】

使用abstract关键字修饰的方法叫做抽象方法,修饰的类叫做抽象类。【重点】

抽象类不一定含有抽象方法,含有抽象方法的类一定是抽象类;

抽象类不能实例化;

子类继承抽象父类必须重写抽象方法。

接口是一个特殊的抽象类,可以实现多继承:【重点】

接口只允许包含常量与抽象方法;

JDK8.0后可以包含一个默认方法和静态方法。


网站公告

今日签到

点亮在社区的每一天
去签到