1.抽象类
1.1什么是抽象类
抽象类,其实就是它就是一个抽象的类,就是不具体的,没有具体方法去实现的类,不能完全代表一个具体的对象,也无法想普通的类一样直接去实例化,用关键字abstract修饰的类,就是抽象类。具体格式:
abstract class 类名{
...
}
而除了类,可以是不具体的,叫做抽象类,我们在抽象类中的方法,也可以是不具体的,抽象的,也就是抽象方法,
1.2关于抽象类
关于抽象类,
1.在java中,一个类如果被abstract修饰就被称为抽象类,抽象类中被abstract修饰的方法被称为抽象方法,抽象方法中不需要写出具体的代码块。
abstract class Animal{
abstract public void eat();
}
2.抽象类也可以像普通类一样定义成员变量和成员方法,甚至是构造方法。而且抽象类中不一定要有抽象方法,但是抽象方法一定要在抽象类中。
3.普通类是可以实例化的,但是抽象类不能进行实例化。
4.当普通类继承了抽象类,那普通类中一定要重写抽象类中的抽象方法。
5.当一个抽象类B继承了另一个抽象类A,该抽象类B可以先不重写抽象方法,但是当有普通类C继承抽象类B,仍然需要重写所有的抽象方法。
6.抽象方法不能是private的,也不能被final和static修饰,因为抽象方法要被子类重写。
7.抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量。
1.3抽象类的作用
抽象类本身不能直接使用,只能通过创建该的抽象类的子类,然后在子类中重写抽象方法。但是对于普通的方法,普通的类,我们也可以直接去继承然后重写。而使用抽象类的主要作用是,相当于多了一重编译器的校验。
因为,当父类作为抽象类时,抽象方法存在于父类中,而抽象方法并没有具体代码去实现,实际工作就不会在父类中完成,而由子类完成。此时如果不小心误用成父类了,普通类编译器时不会报错的,但是父类是抽象类就会在实例化的时候提示错误。而且将需要实现的工作用抽象方法写于抽象类中,子类必须重写所有的抽象方法,所以也不会漏掉我们要实现的方法。
2.接口
2.1接口
关于接口在我们生活中的出现其实随处可见,比如说电脑上的USB接口,还有日常用电的排插接口等等,其实接口就是只要大家有着一样的规范标准,我们都可以将它进行使用。
而在中接口可以看成是多个类的公共规范,是一种引用数据类型。
2.2语法规则
接口的定义格式与定义类的格式基本相同,将class关键字换成interface关键字,就定义了一个接口。
public interface 接口名称 {
//抽象方法
}
而在接口中,我们有几种抽象方法的写法
public interface ITest{
public abstract void test1();
public void test2();
abstract void test3();
void test4();//一般更推荐test4的写法,更简洁。
}
而关于接口的命名,一般以大写字母I开头,加上形容词性的单词。接口中的抽象方法尽量的简洁。
我们还需要注意:
1.接口中的方法,是默认使用public abstract修饰的。
2.接口中的方法虽然默认是不能有实现的方法,但是静态方法可以有具体的实现,还有被default关键字修饰的方法也可以。
public interface ITest{
void test1();
public static void test2(){
.....
};
default public void test3(){
.....
}
}
3.接口中也可以添加成员变量,而且默认是 public static final 修饰的。
4.接口也不能过通过new关键字进行实例化。
ITest itest = new ITest(); //Error
2.3接口的使用
由于接口不能直接使用,所以我们必须通过一个类来“实现”该窗口,实现接口中所有的抽象的抽象方法,所以我们需要使用关键字implement来将类和接口进行关联
class 类名 implement 接口名{
....
}
子类与父类之间是extends的继承关系,类与接口之间是implement实现关系。
当一个类实现一个接口后,类里必须重写接口里的所有方法,但是当接口中存在default修饰的方法时,可以重写也可以不重写。
interface Animal{ abstract public void eat(); default public void kind(){ System.out.println("生活在什么地方!"); } } class Dog implements Animal{ @Override public void eat() { System.out.println("在吃狗粮!!"); } @Override public void kind() { System.out.println("生活在陆地"); } } class Cat implements Animal{ @Override public void eat() { System.out.println("在吃猫粮"); } }
接口与抽象类都一样,可以通过向上转型的方式,进行使用,以上述代码为例,我们要在主类中:
public class Test { public static void AnimalEat(Animal animal){ animal.eat(); } public static void main(String[] args) { AnimalEat(new Dog()); AnimalEat(new Cat()); } }
2.4实现多个接口
之前,关于继承,在java中是不能进行多继承的,但是当我们生活中的一些东西,都拥有共同的或者不同的一些共性时,比如说一些动物,狗既能有用又能跑,而猫只能跑,鸭子能跑,能飞,能游泳等等,只用继承就无法表示这些特性,所以我们就需要用到接口。
接口可以解决java中多继承的问题。
首先我们先创建一个动物类
abstract class Animal{ private String name;//此处利用了封装 private int age; public Animal(String name,int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public abstract void eat(); }
然后写入一些接口将动物特性分类。
interface IFlying { void flying(); } interface IRunning{ void running(); } interface ISwimming{ void swimming(); }
最后我们就进行继承和接口,去实现某只动物。
class Dog extends Animal implements IRunning,ISwimming{ public Dog(String name,int age) { super(name, age); } @Override public void eat() { System.out.println(this.getName() + "在吃狗粮!"); } @Override public void running() { System.out.println(this.getName() + "在乱跑!!"); } public void swimming(){ System.out.println(this.getName()+ "正在狗刨!"); } }class Bird extends Animal implements IFlying,ISwimming{ public Bird(String name, int age){ super(name,age); } @Override public void eat() { System.out.println(this.getName()+ " 正在吃鸟粮!"); } @Override public void flying() { System.out.println(this.getName()+ "正在飞!"); } }
当我们要写某只动物的类时,一定是先继承,再用接口实现。!!!
最后我们就在主类中利用向上转型运行代码。
public static void run(IRunning iRunning){ iRunning.running(); } public static void swim(ISwimming iSwimming){ iSwimming.swimming(); } public static void fly(IFlying iFlying){ iFlying.flying(); } public static void test1(Animal animal){ animal.eat(); } public static void main(String[] args) { Animal animal = new Dog("wangwang",1); test1(animal);//在这一种通过继承方式的调用中,只能是动物类才能使用eat()方法。 Animal animal1 = new Bird("jiujiu",1); test1(animal);//这样的方法展现多态性 run(new Dog("wangwang",1));//而直接用接口的方法,不管你是不是动物类,只要你定义了 //一个新类,都可以直接通过接口去对类进行调用。 swim(new Dog("wangwang",1)); }
可以得到运行结果
在最后主方法中利用接口去接受动物的特性,这种好处就是我们可以直接去调用特性,不必在意它是否是什么类型,都可以直接去完成。
2.5接口间的继承
interface IElectric{ void Electric(); } interface ITransportation{ void Transportation(); } interface IElectricTransportation extends IElectric,ITransportation{ void ElectricTransportation(); }class ElectroMobile implements IElectricTransportation{ .... }
通过创建一个接口“IElectricTransportation”叫做电能交通来继承,“IElectric”叫做用电的,接口。和“ITransportation”交通工具接口,从而实现接口创建的ElectrMobile,电瓶车类。
所以,我们可以总结一下
在类与类之间,我们可以用extends来继承他们之间关系。
在类与接口中,我们在类里用implement来实现接口。
现在我了解到,接口与接口之间也可用通过extends来进行关联,在一个新接口中拓展成新接口。
2.6抽象类和接口的区别
抽象类中,不仅可以有抽象方法,还可以包含普通类,或者成员变量,普通字段,而且这些普通类,普通字段,成员方法可以在抽象类中直接使用,除了抽象类以外的类,都不用被重写。
而接口中,不能包含普通方法,在里面的方法默认都是public abstrac的类型,成员变量都是public static final类型,而且在接口中的方法在后面都必须全部重写。
除此之外,抽象类的子类用extends来继承抽象类
接口用implement来实现接口。
一个抽象类中可以实现若干个接口,而接口不能继承抽象类,但是接口可以用extends来继承多个接口来达到多个接口的功能结合。
所以我们也可以看出,一个子类只能继承一个抽象类,而一个接口可以实现多个接口的功能。