一:抽象类:
1:什么是抽象类:
在面对对象中,所有的对象都是通过类来描述的,但是所有的类并不都是用来描述对象,比如抽象类:抽象类并不能描述一个具体的对象。
例如:动物:
我们知道,动物包括狗,猫,…。如果单从动物这两个字是无法知道要描述什么对象的,所以我们把动物类称为抽象类。
2:为什么有抽象类:
从继承知识可知,当子类继承父类时,就拥有了父类的成员变量和成员方法;从多态的知识可知,我们往往需要重写父类的方法,然后通过向上转型去调用子类中重写的方法;那么父类中被重写的方法就没有调用,但该方法必须存在,那么我们就可以把父类定义为抽象类,父类中的该方法定义为抽象方法。
抽象类的出现就是为了被继承,重写抽象类抽象方法
3:语法:
被abstract修饰的类称为抽象类
被abstract修饰的方法称为抽象方法,抽象方法没有具体的实现
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):子类重写父类的抽象方法
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)子类定义为抽象类:
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,表示类实现了接口
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修饰,其他情况下都会报错,
interface Run{ private abstract void run(); protected abstract void fun1(); public abstract static void fun2(); }
如果没写,编译器默认该方法是被punlic abstract修饰。
interface Run{ public abstract void run(); void fun1();//默认被public abstract修饰 public void fun2();//默认被public abstract修饰 }
3:接口中的方法不能在接口中实现,因为该方法是抽象方法,只能被实现该接口的类重写。
4:因为接口中的方法都是被访问权限限定符:public 修饰,所以重写时,该方法只能被public修饰
5:接口中的成员变量默认是public static final修饰,
interface Run{ public static final int a1=1; public int a2=2;//默认是被 public static final修饰 public static int a3=3;//默认是被 public static final修饰 }
其他情况下会报错:
interface Run{ public static final int a1=1; private int a2=2; default static int a3=3; }
6:接口中不能有静态,实例代码块和构造方法
interface Run{ public static final int a1=1; static { System.out.println("haha"); } { System.out.println("haha"); } public Run(){ } }
7:接口虽然不是类,但接口编译后的字节码文件的后缀格式也是.class
8:如果一个类实现了一个接口,但没有重写接口中的所有的抽象方法,则把该类定义为抽象类(不然编译器会报错)
5:多接口的实现:
在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关键字。
当一个类实现了继承了其他接口的接口时,这个类需要重写这个接口的方法和该接口继承的其他接口的方法。
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(); } }