抽象类和接口
一:抽象类:
1:什么是抽象类:
在面对对象中,所有的对象都是通过类来描述的,但是所有的类并不都是用来描述对象,比如抽象类:抽象类并不能描述一个具体的对象。
例如:动物:
我们知道,动物包括狗,猫,...。如果单从动物这两个字是无法知道要描述什么对象的,所以我们把动物类称为抽象类。
2:为什么有抽象类:
从继承知识可知,当子类继承父类时,就拥有了父类的成员变量和成员方法;从多态的知识可知,我们往往需要重写父类的方法,然后通过向上转型去调用子类中重写的方法;那么父类中被重写的方法就没有调用,但该方法必须存在,那么我们就可以把父类定义为抽象类,父类中的该方法定义为抽象方法。
抽象类的出现就是为了被继承,重写抽象类抽象方法
3:语法:
被abstract修饰的类称为抽象类
被abstract修饰的方法称为抽象方法,抽象方法没有具体的实现
java
abstract class Animal{//被abstract修饰的类称为抽象类
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void eat();//被abstract修饰的方法称为抽象方法,抽象方法没有具体的实现
}
class Dog extends Animal{
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(this.name+"吃狗粮");
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog("旺财",2);
Animal animal=dog;
animal.eat();
}
}
4:抽象类的特点:
1:抽象类不能被实例化;
2:抽象方法不能被private,static ,final,修饰,因为抽象方法是要被重写的;
3:抽象类要被继承,并且继承后的子类要重写父类中的抽象方法,否则把子类定义为抽象类;
(1):子类重写父类的抽象方法
java
abstract class Animal{//被abstract修饰的类称为抽象类
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void eat();//被abstract修饰的方法称为抽象方法,抽象方法没有具体的实现
}
class Dog extends Animal{
public Dog(String name, int age) {
super(name, age);
}
@Override//子类重写父类中的抽象方法
public void eat() {
System.out.println(this.name+"吃狗粮");
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog("旺财",2);
Animal animal=dog;
animal.eat();
}
}
(2)子类定义为抽象类:
java
abstract class Animal{//被abstract修饰的类称为抽象类
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void eat();//被abstract修饰的方法称为抽象方法,抽象方法没有具体的实现
}
abstract class Dog extends Animal{
public Dog(String name, int age) {
super(name, age);
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog("旺财",2);//此时子类也不能实例化,因为此时子类也是抽象类
Animal animal=dog;
animal.eat();
}
}
4:抽象类不一定有抽象方法,但有抽象方法的一定是抽象类;
5:抽象类中可以有构造方法(当子类创建对象时,初始化父类的成员变量)。
6:抽象类中可以有成员变量,普通成员方法,抽象成员方法,构造方法
二:接口:
1:什么是接口:
联想我们日常生活中的事物:
电脑的USB接口:可以插U盘,鼠标,等符合特定规格的器件
电源插座接口:可以插电脑,手机,电视等设备。
可以把接口理解成行为规范的标准,当符合行为规范时就可以使用。
在Java中,接口就是类的行为规范,当类实现这个接口时,就可以重写接口中的抽象方法。
2:为什么有接口:
Java中是不可以多继承的,只能单继承,但是一个类可以实现多个接口,间接解决了这个问题。
3:语法:
接口名前使用interfaace修饰
类和接口之间使用implements,表示类实现了接口
java
interface Run{
public abstract void run();
}
abstract class Animal{
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal implements Run{
public Dog(String name, int age) {
super(name, age);
}
@Override
public void run() {
System.out.println(this.name+"正在跑");
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog("旺财",3);
dog.run();
}
}
4:接口特点:
1:接口不能被实例化
2:接口中的方法必须被punlic abstract修饰,其他情况下都会报错,
java
interface Run{
private abstract void run();
protected abstract void fun1();
public abstract static void fun2();
}
如果没写,编译器默认该方法是被punlic abstract修饰。
java
interface Run{
public abstract void run();
void fun1();//默认被public abstract修饰
public void fun2();//默认被public abstract修饰
}
3:接口中的方法不能在接口中实现,因为该方法是抽象方法,只能被实现该接口的类重写。
4:因为接口中的方法都是被访问权限限定符:public 修饰,所以重写时,该方法只能被public修饰
5:接口中的成员变量默认是public static final修饰,
java
interface Run{
public static final int a1=1;
public int a2=2;//默认是被 public static final修饰
public static int a3=3;//默认是被 public static final修饰
}
其他情况下会报错:
java
interface Run{
public static final int a1=1;
private int a2=2;
default static int a3=3;
}
6:接口中不能有静态,实例代码块和构造方法
java
interface Run{
public static final int a1=1;
static {
System.out.println("haha");
}
{
System.out.println("haha");
}
public Run(){
}
}
7:接口虽然不是类,但接口编译后的字节码文件的后缀格式也是.class
8:如果一个类实现了一个接口,但没有重写接口中的所有的抽象方法,则把该类定义为抽象类(不然编译器会报错)
5:多接口的实现:
在Java中只能单继承,但可以实现多个接口
当实现多个接口时,每个接口中的方法都要被重写
java
public 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();
}
public interface Run {
public abstract void run();
}
public interface Swimming {
public abstract void swimming();
}
public interface Fly {
void fly();
}
public class Dog extends Animal implements Run,Swimming{
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(this.getName()+"吃狗粮");
}
@Override
public void run() {
System.out.println(this.getName()+"会跑");
}
@Override
public void swimming() {
System.out.println(this.getName()+"会游泳");
}
}
public class Bird extends Animal implements Run,Fly{
public Bird(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(this.getName()+"吃鸟粮");
}
@Override
public void fly() {
System.out.println(this.getName()+"会飞");
}
@Override
public void run() {
System.out.println(this.getName()+"会跑");
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog("旺财",2);
dog.run();
dog.swimming();
Bird bird=new Bird("布谷",1);
bird.run();
bird.fly();
}
}
5:接口间的拓展:
在Java中,,类和类之间是单继承的,但接口与接口可以进行拓展(多继承),达到代码复用的效果。
接口间的继承使用extends关键字。
当一个类实现了继承了其他接口的接口时,这个类需要重写这个接口的方法和该接口继承的其他接口的方法。
java
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;
}
}
interface Run{
public abstract void run();
}
interface Swim{
void swim();
}
interface Action extends Run,Swim{
//Action接口拓展了Run,Swim接口
void action();
}
class Dog extends Animal implements Action{
//既要重写Action中的方法,也要重写Run,Swim中的方法
public Dog(String name, int age) {
super(name, age);
}
@Override
public void action() {
System.out.println(this.getName()+"开始行动了");
}
@Override
public void run() {
System.out.println(this.getName()+"正在跑");
}
@Override
public void swim() {
System.out.println(this.getName()+"正在游泳");
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog("旺财",2);
dog.action();
dog.run();
dog.swim();
}
}