抽象类
一、抽象类基本概念
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰。
public abstract class 类名
二、抽象类的特点
抽象类不能实例化→不加 {}
抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
抽象类必须被继承,并且被继承后子类要重写父类中所有的抽象方法,否则子类也是抽象类,必须要用abstract修饰
public abstract class Animal {
abstract void eat();
abstract void sleep();
}
public class Dog extends Animal {
@Override
void eat() {
}
@Override
void sleep() {
}
}
public abstract class Cat extends Animal{
@Override
void eat() {
}
}
三、抽象类的使用
package com.wz.abstractdemo;
abstract class A{//定义一个抽象类
public void fun(){//普通方法
System.out.println("存在方法体的方法");
}
public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
public class TestDemo {
public static void main(String[] args) {
A a = new A();
}
}
运行:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot instantiate the type A
at com.wz.abstractdemo.TestDemo.main(TestDemo.java:15)
四、抽象类的几点说明
1.抽象方法不能包含在非抽象类中。如果抽象父类的子类不能实现所有的抽象方法,那么子类也必须定义为抽象的。而且,抽象方法是非静态的。
2.抽象类不能使用new操作符来初始化。但是,仍然可以定义它的构造方法,这个构造方法在它的子类的构造中调用。
3.包含抽象方法的类必须是抽象的
4.子类可以重写父类的方法并将它定义为抽象的
5.即使子类的父类是具体的,这个子类也可以是抽象的。
6.不能使用new操作符从一个抽象类创建一个实例,但是抽象类可以用作一种数据类型。因此,下面的语句创建一个元素是GeometricObject类型的数组是正确的:
GeonetricObject [ ] objects = new GeometricObject [10]
接口
一、接口基本概念
接口是一种与类相似的结构,用于为对象定义共同的操作
接口在许多方面都与抽象类很相似,但是它的目的是指明相关或者不相关类的对象的共同行为。
为了区分接口和类,采用下面的语法来定义接口:
modifier interface 接口名称{
/** Constant declarations */
/** Abstract method signatures */
}
接口的定义格式与类的定义格式基本相同,将class关键字换成interface关键字,就定义了一个接口。
提示:
1. 创建接口时,接口的命名一般以大写字母I开头
2. 接口命名一般使用形容词词性的单词
二、接口的使用
下面来看一个例子:
public interface Edible {
/** Describle how to eat */
public abstract String howToEat();
}
public class TestEdible {
public static void main(String[] args) {
Object[] objects = {new Tiger(),new Chicken(),new Apple()};
for(int i=0;i<objects.length;i++) {
if(objects[i] instanceof Edible)
System.out.println(((Animal)objects[i]).howToEat());
if(objects[i] instanceof Animal) {
System.out.println(((Animal)objects[i]).sound())
}
}
}
}
abstract class Animal{
private double weight;
public double getWeigt() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
/** return animal sound */
public abstract String sound();
}
class Chicken extends Animal implements Edible {
@Override
public String howToEat() {
return "Chicken:Fry it";
}
@Override
public String sound() {
return "Chicken: cook-a-doodle-doo";
}
}
class Tiger extends Animal{
@Override
public String sound() {
return "Tiger:RROOAARR";
}
}
abstract class Fruit implements Edible{
// Data fields, constructors, and methods omitted here/
}
class Apple extends Fruit{
@Override
public String howToEat() {
return "Apple: Make apple cider";
}
}
class Orange extends Fruit{
@Override
public String howToEat() {
return "Orange: Make orange juice";
}
}
运行结果:
这个例子使用了多个类和接口,它们的继承关系如图所示:
Edible是Chicken 和 Fruit 的父类型,Animal 是 Chicken 和 Tiger 的父类型。Fruit 是 Orange 和 Apple 的父类型
三、接口特性
1. 接口是一种引用类型,但是不能直接new接口对象
public class TestUSB {
public static void main(String[] args) {
USB usb = new USB() ; //编译报错:USB是抽象的,无法实例化
}
2. 接口中的方法不能在接口中实现,只能由实现接口的类来实现
public interface USB {
void openDevice();
void closeDevice(){
System.out.println("关闭设备"); //编译错误,接口中的方法默认为抽象方法
}
}
3.接口虽然不是类,但是编译完成后的字节码文件的后缀也是.class
4.如果类没有实现结合中的所有抽象方法,则类必须设置为抽象类
接口与抽象类的区别
主要区别:抽象类中可以包含普通字段和普通方法,这样的字段和方法可以被子类直接使用(不必重写),接口中不能包含普通方法,子类必须重写其所有抽象方法
接口的使用和抽象类的使用基本类似,但是,定义一个接口与定义一个抽象类有所不同。如图:
Java只允许为类的继承做单一继承,但是允许使用接口做多重继承。例如,
public interface IRunning {
void run();
}
public interface ISwimming {
void swim();
}
public interface IAmphibious extends IRunning,ISwimming{
}
class Frog implements IAmphibious{
}
所有的类共享同一个根类Object,但是接口没有共同的根。与类相似,接口也可以定义一种类型。一个接口类型的变量可以引用任何实现该接口的类的实例。如果一个类实现了一个接口,那么这个接口就类似于该类的一个父类。可以将接口当作一种数据类型使用,将接口类型的变量转换为它的子类,反过来也可以。例如,假设c是图中Class Z的一个实例,那么c也是0bject、Class1、 Interface1 、 Interface1 _1、 Interface1 _2 Interface2_1 和 Interface2 _2的实例。