其他Java基础文章
1、接口的基础语法
- 接口是Java独有的语法,C++中没有接口。
- Java的接口其实就是抽象类,一个接口就是一个抽象类。
上面的91个字节就是差在构造方法上。因为接口是没有构造方法的。
上面接口的实现类:MyClass
,接口IA
中的抽象方法:m1和m2
会继承给MyClass
。①MyClass要么成为:abstract class MyClass implements IA{}
,②将接口里面的方法都实现了,因为那些方法都是抽象的。别忘了加修饰符:public
,因为接口中的默认为:project
,而实现类中如果不加默认是:default
,根据覆盖的语法要求(相同或范围更宽的),不能小于父类的范围,所以要手动添加:public
。
2、接口和类的关系
接口怎么用呢?
首先,接口可以声明引用
,但是接口不能创建对象:IA a = new IA()
,【因为接口是抽象类】。但是可以创建一个:IA a = new MyClass();
,这相当于是把子类对象赋值给父类引用(多态)。a.m1(); a.m2()
最终调用的是实现类MyClass中的m1()和m2()方法。
接口的特殊语法特点:
1、接口和接口之间也能继承(extends);
2、Java中的类之间是只支持单继承的,但是接口之间可以多继承
;
3、一个类可以同时继承另一个类和实现多个接口;
package com.jun.sept1722;
public class TestInterface {
public static void main(String[] args) {
MyClass mc = new MyClass();
IA a = mc;
IB b = mc;
IC c = mc;
ID d = mc;
ClassE e = mc;
a.m1();
a.m2();
b.m3();
c.m4();
d.m3();
d.m4();
d.m5();
e.m6();
}
}
abstract class ClassA{
public static final int A = 10;
public static final double B = 2.5;
public abstract void m1();
public abstract void m2();
public ClassA(){}
}
interface IA {
int A = 10;
double B = 2.5;
void m1();
void m2();
}
interface IB {
void m3();
}
interface IC {
void m4();
}
interface ID extends IB,IC { // 接口之间可以多继承
void m5();
}
abstract class ClassE {
public abstract void m6();
}
class MyClass extends ClassE implements IA, ID {
public void m1(){}
public void m2(){}
public void m3(){}
public void m4(){}
public void m5(){}
public void m6(){}
}
3、多继承的复杂性
1、子类引用可以直接赋值给父类引用;
2、父类引用需要强转才能赋值给子类引用;
3、没有继承关系的两种类型之间不能强转赋值。
4、强转的两种类型中,如果包含接口类型,强转代码一定编译通过。
4、接口与多继承
在上述这种情况下,Snoopy类不可能既继承Dog类,又实现Person类。
5、接口的解耦合
public class TestInterface2 {
public static void main (String[] args) {
Light light = new Light();
RedBulb bulb1 = new RedBulb();
light.setBulb(bulb1);
light.powerOn();
YellowBulb bulb2 = new YellowBulb();
// 如果需要用faGuang2()方法,需要对Light类进行修改。太麻烦!
// 引出接口的解耦合
}
}
class Light {
private RedBulb bulb;
public void setBulb(RedBulb bulb) {
this.bulb = bulb;
}
public void powerON(){
bulb.faGuang1();
}
}
class RedBulb {
public void faGuang1 (){
System.out.println("发出红光");
}
}
class YellowBulb {
public void faGuang2 () {
System.out.println("发出黄光");
}
}
接口作为标准,使接口的使用者和接口的实现者分离,从而实现弱耦合关系。JDBC技术就是典型的接口解耦合
package com.jun.sept1722;
public class TestInterface2 {
public static void main (String[] args) {
Light light = new Light();
RedBulb bulb1 = new RedBulb();
light.setBulb(bulb1);
light.powerOn();
YellowBulb bulb2 = new YellowBulb();
light.setBulb(bulb2);
light.powerON();
}
}
class Light {
private Bulb bulb;
public void setBulb(Bulb bulb) {
this.bulb = bulb;
}
public void powerOn(){
bulb.shine();
}
}
interface Bulb { // 制定一个标准
void shine();
}
class RedBulb implements Bulb{
public void shine(){
System.out.println("发出红光");
}
}
class YellowBulb implements Bulb{
public void shine() {
System.out.println("发出黄光");
}
}
6、接口的回调
接口的回调:程序员负责实现接口,从而实现接口中的方法。而不用关心方法何时被谁调用。
1、Java中有了接口,才出现了一种回调的编程方式。
2、你负责实现接口,而最终提供方法被别人调用,这种编程的套路,就叫做接口的回调。
3、由于有了接口回调,Java才能把开发中最为通用的一些功能抽取出来,而把需要程序员来实现的业务功能通过接口隔离开
,让程序员自己去实现,从而形成各种的开发框架。
public class TestSort {
public static void main(String[] args) {
Student[] stu = new Student[]{
new Student("Lucy", 18 ),
new Student("Mike", 26),
new Student("Jesse", 23),
new Student("White", 35)
};
java.util.Arrays.sort(stu); // Student cannot be cast to java.lang.Comparable
// 将Comparable接口中的compareTo方法实现好后的结果(按年龄排):
/*Student name = Lucy, age = 18
Student name = Jesse, age = 23
Student name = Mike, age = 26
Student name = White, age = 35*/
for (int i = 0; i < stu.length; i++) {
stu[i].print();
}
}
}
class Student implements Comparable<Student>{
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void print() {
System.out.println("Student name = " + name + ", age = " + age);
}
/*
this 和 s 比大小
this < s (this排在s前面) 则返回负数
this > s (this排在s后面) 则返回正数
this == s 则返回0
*/
public int compareTo(Student s) {
if (this.age < s.age) {
return -1;
} else if (this.age > s.age) {
return 1;
} else {
return 0;
}
}
}
7、接口进阶
按照接口的常见用途,可以分为
1、最常见的接口:里面有一些抽象的方法:public abstract
2、常量接口:因为是公开静态的:public static final ,所以使用时直接:接口名.属性名
3、标记接口(空接口):interface Empty{}
仅仅是给类打一个标记
一种设计模式:缺省适配模式
理解:定义一个接口的同时,往往会定义一个抽象类, 把接口的方法都实现。这个抽象类实现了(implements)这个接口。
- 发布接口的同时发布一个实现了该接口的抽象类。这样就提供了一种选择:
如果继承抽象类,间接的也就实现了该接口
。当然你也可以选择直接来实现该接口。- 通过继承抽象类来实现该接口的好处:因为在抽象类中已经实现了接口中的方法。但都是空的,毫无意义的实现(
默认的实现,缺省的实现
)。当你继承这个抽象类的时候,你可以选择性的覆盖你想要的方法
,你不感兴趣的方法,就沿用父类这种无意义的实现就好了。但如果是直接实现接口的话,你必须实现接口中的所有方法
。 - 继承这种抽象类的坏处:失去了继承别的类的机会。直接实现接口的话还是可以选择继承别的类的。
写这种抽象类的目的不是去 new 对象的。是让你拿去继承的
。所以尽管里面没有抽象方法,还是将它定义成抽象类。