接口
有时我们需要不从多个不相关的类中设计一个子类,而JAVA只支持单继承,这时可以使用接口的多继承来完成.
接口也可以视为一种抽象类,但是与抽象类又有很多的不同.
接口的特点:
1.使用public interface 修饰,不使用class修饰.
2.只能有抽象方法和常量(public static final)
3.不能实例化(即不能new)
4.不能提供构造器.
接口的实现
1.子类需要实现接口的所有抽象方法,若未能全部实现则需要定义为抽象类.
2.使用implements关键字,需要实现的接口用逗号隔开.
接口间的继承
接口继承接口依然使用extends关键字.
下面用一个案例来解释上面的相关知识:
interface A{
public static final int NUMBER=1;
void sum();
}
interface B extends A{
/*继承接口A*/
void mul();
}
class C implements B{
/*接口B继承了接口A,也继承了方法,所以C类必须全部实现.*/
public void sum(){}
public void mul(){}
}
abstract class D implements A,B{
/*
同时实现多个接口用逗号隔开
未实现所有方法,所以类名要使用abstract修饰.
*/
public void mul() {}
}
多态
向上造型:
父类型的变量引用子类型的对象.
1.同父类型的变量指向不同的子类型对象,调用的功能有不同的实现
2.不同的父类型指向同一个对象有不同的功能.
向下造型:
将父类型(接口)的变量赋值给子类型变量或者是其他父类型(接口)的变量.
多态的示例代码:
public class Test {
public void outPut(){
System.out.println("父类的输出语句.");
}
public void supMethod(){
System.out.println("父类独有的方法输出语句.");
}
public static void main(String[] args) {
Test t=new Test();
t.outPut();
t.supMethod();
System.out.println("=====向上造型======");
Test t1=new Sub();
t1.outPut();
t1.supMethod();
t1=new Sub2();
t1.outPut();
System.out.println("=====向下造型=====");
Test t2=new Sub();
Sub s=(Sub) t2;
s.subMethod();
s.supMethod();
s.outPut();
}
}
class Sub extends Test{
public void outPut() {
System.out.println("子类1的输出语句.");
}
public void subMethod(){
System.out.println("子类独有的方法输出语句.");
}
}
class Sub2 extends Test{
public void outPut() {
System.out.println("子类2的输出语句.");
}
}
运行结果:
父类的输出语句
父类独有的方法输出语句.
=====向上造型======
子类1的输出语句.
父类独有的方法输出语句.
子类2的输出语句.
=====向下造型=====
子类独有的方法输出语句.
父类独有的方法输出语句.
内部类
定义在一个类内部的新类型,另外一个类称为外部类.
根据位置不同可分为:
成员内部类,方法(局部)内部类,带static修饰的静态内部类,匿名内部类.
成员内部类:
以类的成员来定义,可以使用任意修饰词,调用外部类变量时,自动添加了外部类名.this.外部类变量名,
四种访问权限修饰符都可以使用.
示例代码:
public class Test {
String outName;
innerClass i;
public Test(String outName){
this.outName=outName;
i=new innerClass("成员内部类.");
}
public void outPut(){
System.out.println("外部类的输出语句,输出成员内部类变量:"+i.innerName);
i.outPut();
}
class innerClass{
String innerName;
public innerClass(String innerName){
this.innerName=innerName;
}
public void outPut(){
System.out.println("成员内部类的输出语句,访问外部类变量;"+Test.this.outName);
}
}
public static void main(String[] args) {
Test t=new Test("外部类.");
t.outPut();
}
}
运行结果:
外部类的输出语句,输出成员内部类变量:成员内部类.
成员内部类的输出语句,访问外部类变量;外部类.
方法(局部)内部类:
定义在方法中,相当于局部变量,仅限于方法内使用,定义时不能使用修饰词,可以直接访问外部类的非静态成员变量.
示例代码:
public class Test {
public void innerClass(){
class inner{//方法内部类
/*各种写法都跟正常的类一样.*/
int num1;
int num2;
public inner(int num1,int num2){
this.num1=num1;
this.num2=num2;
}
public void outPut(){//方法
System.out.println("方法内部类的输出语句.");
System.out.println("num1="+num1+",num2="+num2+".");
}
}
//实例化
inner i=new inner(5,6);
//调用方法
i.outPut();
}
public static void main(String[] args) {
Test t=new Test();
t.innerClass();
}
}
运行结果:
方法内部类的输出语句.
num1=5,num2=6.
带static修饰的静态内部类:
也是以类的成员定义的,多了一个static修饰词,相当于静态成员变量.能直接访问外部类的静态成员变量.
示例代码:
public class Test {
//外部类静态变量
static int num1=1;
/*静态内部类*/
static class inner{
String name;
public inner(String name){
this.name=name;
}
public void showInner(){
//可以直接使用外部类静态变量num1
System.out.println("外部类的静态变量num1:"+num1+",静态内部类的变量name:"+name);
}
}
public static void main(String[] args) {
inner i=new inner("静态内部类");
i.showInner();
}
}
运行结果:
外部类的静态变量num1:1,静态内部类的变量name:静态内部类
匿名内部类:
想使用某个抽象类,类,接口的子类对象时,因为我们只用一次,此时我们无须定义子类的结构,因此我们可以使用匿名内部类的写法,因为没有子类名称,我们可以向上造型
=new 想定义的子类的父类(){
重写接口/抽象类里面的所有抽象方法,或重写实现方法.
};
其实可以用俄罗斯方块案例中的键盘监听用作匿名内部类实例:
KeyListener l=new KeyAdapter() {
public void keyPressed(KeyEvent e) {
/*重写的方法*/
int code=e.getKeyCode();
.......
}
};