1.接口(interface):接口的地位等同于Class,接口中的所有方法都是抽象方法。在声明接口中的方法时,可以使用abstract关键字,也可以不使用。通常情况下,都会省略掉abstract关键字。因为已经规定了接口中的所有方法都是抽象方法,所以有写与无写都无所谓。可以看出接口也是起到一种规范约束的作用和抽象类是一样的。
public interface InterfaceTest
{
public abstract void output();
}
通常情况下,都是这么写,abstract关键字省略。
public interface InterfaceTest
{
public void output();
}
如果接口里面定义非抽象方法,如下所示:
public interface InterfaceTest
{
public void output()
{
}
}
执行结果错误:
D:\src>javac InterfaceTest.java
InterfaceTest.java:4: 错误: 接口方法不能带有主体
{
^
1 个错误
2.可以将接口看作是特殊的抽象类(抽象类中可以有具体方法,也可以有抽象方法,而接口中只能有抽象方法,不能有具体方法)。注意接口跟抽象类一样,不能new一个接口。用new关键字。
3.类可以实现接口。实现使用关键字implements表示,代表了某个类实现了某个接口。
4.一个类实现了某个接口,那么该类就必须要实现接口中声明的所有方法。如果该类是个抽象类,那么就无需实现接口中的方法了。
public class Test3
{
public static void main(String[] args)
{
MyClass myclass = new MyClass();
}
}
interface MyInterface
{
public void output();
}
class MyClass implements MyInterface
{
}
执行结果:
D:\src>javac Test3.java
Test3.java:16: 错误: MyClass不是抽象的, 并且未覆盖MyInterface中的抽象方法output()
class MyClass implements MyInterface
^
1 个错误
【说明】:产生错误原因是因为MyClass是一个非抽象的类,当他实现了MyInterface这个接口时,必须实现接口中的所有方法,而它没有实现output()方法,所以程序出错,有两种解决办法,以下程序为其解决办法。
程序一:实现接口中的方法
public class Test3
{
public static void main(String[] args)
{
MyClass myclass = new MyClass();
myclass.output();
}
}
interface MyInterface
{
public void output();
}
class MyClass implements MyInterface
{
public void output()
{
System.out.println("output");
}
}
编译结果
D:\src>java Test3
output
程序二:将实现接口MyInterface的MyClass类定义为抽象类
public class Test3
{
public static void main(String[] args)
{
// MyClass myclass = new MyClass();
}
}
interface MyInterface
{
public void output();
}
abstract class MyClass implements MyInterface
{
}
编译成功,此时如果想要实现接口中的output()方法,必须再定义一个子类来实现这个接口,同时实现这个接口中的方法。
5.Java是单继承的,也就是说某个类只能有唯一一个父类;一个类可以实现多个接口,多个接口之间使用逗号分隔。注意如果这个类不是抽象的,那么就要实现多个接口当中的所有方法。
同样对上一个程序修改,定义了两个接口,现在要MyClass同时实现这两个接口
public class Test3
{
public static void main(String[] args)
{
MyClass myclass = new MyClass();
myclass.output();
}
}
interface MyInterface
{
public void output();
}
interface MyInterface2
{
public void output2();
}
class MyClass implements MyInterface,MyInterface2
{
public void output()
{
System.out.println("output");
}
}
执行结果:
D:\src>javac Test3.java
Test3.java:22: 错误: MyClass不是抽象的, 并且未覆盖MyInterface2中的抽象方法output2()
class MyClass implements MyInterface,MyInterface2
^
1 个错误
【原因】:MyClass实现了MyInterface接口中的方法,但是没有实现MyInterface2中的方法,所以程序出错。
public class Test3
{
public static void main(String[] args)
{
MyClass myclass = new MyClass();
myclass.output();
}
}
interface MyInterface
{
public void output();
}
interface MyInterface2
{
public void output2();
}
class MyClass implements MyInterface,MyInterface2
{
public void output()
{
System.out.println("output");
}
public void output2()
{
System.out.println("output2");
}
}
执行结果:
D:\src>java Test3
output
output2
继续修改以上程序,继承一个类同时实现多个接口
public class Test3
{
public static void main(String[] args)
{
MyClass myclass = new MyClass();
myclass.output();
myclass.output2();
myclass.output3();
}
}
interface MyInterface
{
public void output();
}
interface MyInterface2
{
public void output2();
}
class MyParent
{
public void output3()
{
System.out.println("output3");
}
}
class MyClass extends MyParent implements MyInterface,MyInterface2
{
public void output()
{
System.out.println("output");
}
public void output2()
{
System.out.println("output2");
}
}
执行结果:
D:\src>java Test3
output
output2
output3
6.多态:所谓多态,就是父类型的引用可以指向子类型的对象,或者接口类型的引用可以指向实现接口的类的实例。关于接口与实现的类之间强制类型转换方式与父类和子类之间的强制类型转换方式完全一样。
public class Test4
{
public static void main(String[] args)
{
AA bb = new BB();
bb.output();
}
}
interface AA
{
public void output();
}
class BB implements AA
{
public void output()
{
System.out.println("BB");
}
}
执行结果:
D:\src>java Test4
BB
【说明】:接口类型的引用可以指向实现接口的类的实例
上面程序代码段第三行也可以这样写,写成向上类型转换。
public static void main(String[] args)
{
BB bb = new BB();
AA aa = bb;
bb.output();
}
编译执行的结果也是一样的。
同样代码段,也可以写成向下类型转换
public static void main(String[] args)
{
/*
//向上类型转换
BB bb = new BB();
AA aa = bb;
bb.output();
*/
//向下类型转换
AA aa = new BB();
BB bb = (BB)aa;
bb.output();
}
编译执行结果也是一样的。
4. static 关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰 类(后面的课程讲)
比较以下两个程序的不同
public class StaticTest
{
public static void main(String[] args)
{
MyStatic mystatic = new MyStatic();
MyStatic mystatic2 = new MyStatic();
mystatic.c = 10;
System.out.println(mystatic2.c);
}
}
class MyStatic
{
int c;
}
执行结果:D:\src>java StaticTest
0
程序二在程序一的第十二行代码段进行修改如下
public class StaticTest
{
public static void main(String[] args)
{
MyStatic mystatic = new MyStatic();
MyStatic mystatic2 = new MyStatic();
mystatic.c = 10;
System.out.println(mystatic2.c);
}
}
class MyStatic
{
static int c;
}
执行结果:
D:\src>java StaticTest
10
【说明】:对于一个属性被static所修饰,不管MyStatic生成了多少实例,那么这多个实例共同使用这个属性。
图15-1
5. static 修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯 一一份静态的成员变量;一个对象对该静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化,如图15-1所示。如果一个成员变量是static的,那么我们可以通过类名.成员变量名的方式来使用它(推荐使用这种方式)。因为此时a不属于任何特定的对象,它是被所有对象所共同拥有的唯一的一份。Java推荐使用类名去访问。
修改以上程序第三行代码段:
public static void main(String[] args)
{
/*
MyStatic mystatic = new MyStatic();
MyStatic mystatic2 = new MyStatic();
mystatic.c = 10;
System.out.println(mystatic2.c);
*/
MyStatic mystatic = new MyStatic();
MyStatic.c = 10;
System.out.println(mystatic.c);
}
执行结果:
D:\src>java StaticTest
10