抽象类和接口
抽象类
- 当一个类中具有抽象方法时,该类就被视为一个抽象类
- final方法不能为抽象方法,这是因为final的方法不能被重写,但是抽象方法必须经过子类重写才能被使用
- 私有方法不能被定义为抽象方法,私有方法并不能被子类继承,而抽象方法必须被子类继承,然后重写实现。
- 静态方法不能被定义为抽象方法,因为抽象方法所在的抽象类是不能创建对象的,也就是不能够被实例化的。但是静态方法是可以通过类名调用,这样调用抽象方法是没有任何意义的
- abstract关键字
abstract抽象修饰符可以修饰方法和类,使用abstract修饰符修饰的方法称为抽象方法,使用abstract修饰符修饰的类称为抽象类。
public class Transport{
//定义抽象方法
public abstract void stop();
}
- 抽象类不能创建对象也就是不能给抽象类创建类的实例(抽象类不能用new创建对象)
Transportation t=new Transportation();//错误的
Transportation t=new Car();//正确
- 当子类继承抽象类时,必须对父类中的所有抽象方法进行重写,如果父类有两个抽象方法那么子类继承后,必须实现父类的两个抽象方法,否则子类也必须定义为抽象类。
//抽象类
public abstract class Transport {
//抽象方法,需要被子类重写
public abstract void stop();
}
//Car类
//继承自抽象类Transport,需要实现(重写)Transport类的所有抽象方法
public class Car extends Transport {
//重写Transport类的抽象方法
@Override
public void stop() {
System.out.println("小轿车用刹车盘刹车");
}
}
//Bike类
//继承自抽象类Transport,需要实现(重写)Transport类的所有抽象方法
public class Bike extends Transport {
//重写Transport类的抽象方法
@Override
public void stop() {
System.out.println("自行车用脚刹车");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//该写法错误,因为抽象类不能被实例化,需要其子类进行实例化
// Transport trans = new Transport();
//通过子类Car进行实例化
Transport trans = new Car();
//通过子类Bike进行实例化
Transport trans1 = new Bike();
trans.stop();
trans1.stop();
}
}
——————————————————
接口
- 接口对外提供的是一个窗口的功能,子类可以同时接收多个接口,而一个子类只能有一个父类,interface是定义接口的关键字,abstract关键字并不是必须的,如果定义时不给出系统也会自动加上。当一个类实现一个接口时,需要使用implements关键字,后面跟上接口名,位置是和extends关键字继承父类一样。
- 接口定义与实现:
[abstract] interface<J接口名>{
//定义在接口中的方法与成员变量
}
- 在接口中定义的变量,实际上是公共的静态变量,格式为:
public static final int p=3;
- 接口中的方法是抽象的不能直接使用,只有在实现接口的类中,重写方法后才能被使用;
- 在实现接口时,一个类可以同时实现多个接口,当一个类实现多个接口时,需要重写所有接口中的所有方法。实现的接口之间使用逗号隔开,如:
//通过interface关键字定义接口
public interface Fly {
//会飞
public void flyable();
}
public interface Eat {
//能吃饭
public void eatable();
}
public interface Clib {
//会爬树
public void clibable();
}
//通过implements关键字实现接口
public class Bird implements Fly {
@Override
public void flyable() {
System.out.println("我会飞,我是一只小小鸟");
}
}
//实现多个接口,需要用逗号隔开
public class Pig implements Eat, Fly, Clib {
@Override
public void eatable() {
System.out.println("我是猪,我很能吃");
}
@Override
public void clibable() {
System.out.println("我是老母猪,我会上树");
}
@Override
public void flyable() {
System.out.println("我会飞,我是飞猪");
}
}
——————————————————
abstract class(抽象类)和interface(接口)语法区别
- 一个类可以实现多个接口,但只能继承一个抽象类;
- 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的
- 抽象类可以有构造方法,接口中不能有构造方法;
- 抽象类中可以有普通成员属性,接口中没有普通成员属性;
- 抽象类中可以包含静态方法,接口中不能包含静态方法;
接口是抽象类的特殊版本。接口可以继承接口;抽象类可以实现(implements)接口;抽象类可以继承具体类;抽象类中可以有静态的main方法;抽象类可以有内部类;接口可以有内部类,但必须是static内部类,但不一定是final的。
抽象类与普通类的区别主要有以下两点:
不能创建实例对象 允许有abstract方法
抽象类不能使用final修饰,因为final修饰的类不能继承修改,抽象类需要继承,接口是抽象类的特殊版本。
- 抽象类中可以存在非抽象方法;接口中的方法全部被修饰为公共的抽象方法;抽象类里可以有私有的方法和私有的成员变量;一个类只能继承一个抽象类,Java只支持单继承。
- 接口中的方法全部被修饰为公共的抽象方法;接口里的方法必须全部实现;接口里的方法都被修饰为public abstract类型的、接口里的变量都被修饰为public static final类型的;一个类可以实现一个接口,也可以实现多个接口。
——————————————————————————————————————
嵌套类和内部类
- 嵌套类分为两种类型:静态嵌套类和非静态嵌套类。平常我们使用的最多的是非静态嵌套类,也就是被称为内部类,其中内部类又可以分为三种:
在一个类(外部类)中直接定义的内部类
在一个方法(外部类的方法)中定义的内部类
匿名内部类
- 在外部类中定义内部类:对于内部类,通常在定义类的class关键字前,不加public或private等修饰词。内部类的成员只在内部类可见,若外部类或同层次的内部类需要访问,需要创建类的对象,不可以直接访问内部类的变量。
public class Test2{
String name="galen";
class InnerOne{
public int a=1;
private int b=2;
int c=3;
public void display(){
System.out.println("name:" +name);
}
}
void test(){
InnerOne ino = new InnerOne();
ino.display();
//System.out.println("InnerOne a:"+a);
//在外层类中的某个方法里面不能直接访问内部内变量 ,必须通过对象来访问
System.out.println("InnerOne a:"+ino.a); //可以访问
System.out.println("InnerOne b:"+ino.b); //可以访问
System.out.println("InnerOne c:"+ino.c); //可以访问
InnerTwo it = new InnerTwo();
it.transfer();
}
class InnerTwo{
InnerOne ino = new InnerOne();
public void transfer(){
//System.out.println(a); //不可访问Innter的y成员
//System.out.println(InnerOne.a);//不可直接访问Inner的任何成 员和方法
ino.display(); //可以访问
System.out.println("sum="+(ino.a+ino.b+ino.c)); //可以访问
}
}
public static void main(String args[]){
Test2 ot = new Test2();
ot.test();
}
}
- 在方法中定义内部类:定义方法中的内部类的可见性更小,它只在方法内部可见,在外部类及外部在类的其它方法中都不可见;特点:方法中的内部类连本方法的成员变量都不可访问,它只能访问本方法的final型成员;在方法中定义成员时,只允许使用final修饰词或不加修饰词。
- 匿名内部类:通常用在java的事件处理上。
//通过abstract关键字定义抽象类
public abstract class Eat {
//能吃饭
public void eatable();
}
public class Person {
public void feed(Eat e){
e.eatable();
}
}
public class Test2{
public static void main(String[] args) {
Person mary = new Person();
mary.feed(new Eat() {
@Override
public void eatable() {
System.out.println("汉堡包");
}
});
}
}
——————————————————————————————————————