1.抽象类
1.1抽象类概念
一个类中没有足够的信息去描述一个具体的对象
1.2抽象类语法
//用abstract来修饰
public abstract class Shape{
...
//抽象方法
abstract public void draw();
//也可以有普通方法
public void func()
//普通成员变量
public int i;
//甚至构造方法
...
}
1.3抽象类特性
//1.抽象类不能直接实例化对象
//抽象类是抽象的,无法进行实例化
//2.抽象方法不能用private来修饰
//抽象方法没加访问限定时默认是public
//3.抽象方法不能被final和static修饰,因为抽象方法要被子类继承并重写
//4.抽象类必须被继承,并且继承后子类需要重写父类的抽象方法,否则子类也将是抽象类,并且需要用abstract来修饰
//5.抽象类中不一定有抽象方法,但是有抽象方法的一定是抽象类
//6.抽象类中可以有构造方法,子类创建对象时,可通过构造方法初始化父类的成员变量
1.4抽象类的作用
抽象类的作用就是让子类重写父类的方法实现功能,父类并不能被实例化,因此抽象类都是由子类发挥作用.
2.接口
2.1接口的概念
一种类的引用数据类型
2.2接口语法格式
//和类的区别就是类这里是class
//接口的名字一般以I开头
public interface 接口名称{
//接口中全部都是抽象方法
//全都默认是public abstract修饰
void method();
}
2.3接口使用
//类和接口之间是用implements连接
public class 类名称 implements 接口名称{
...
}
2.4接口特性
//1.接口是一种引用类型,但是不可以直接new接口的对象
//2.接口中的所有方法皆为默认用public abstract修饰的方法,用其他修饰都会报错
//3.接口中的方法是不能在接口中实现的,都是由接口的类来实现(除非加default修饰)
//4.重写接口中的方法时不能用default默认来修饰
//5.接口中的变量默认被public static final访问修饰,因此不能在子类中被重新赋值
//6.接口中不能有静态方法和静态代码块
//7.如果类没有实现接口中所有的方法,则该类必须被定义为抽象类
2.5实现多个接口
public class Animal {
protected String name;
public Animal(String name){
this.name = name;
}
}
interface IFlying{
void fly();
}
interface IRunning{
void run();
}
interface ISwimming{
void swim();
}
class Cat extends Animal implements IRunning{
public Cat(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在跑");
}
}
class Fish extends Animal implements ISwimming{
public Fish(String name) {
super(name);
}
@Override
public void swim() {
System.out.println(this.name + "在游泳");
}
}
//多接口
//接口中的抽象方法都必须要实现
class Frog extends Animal implements ISwimming,IRunning{
public Frog(String name) {
super(name);
}
@Override
public void run() {
System.out.println("正在往前跳");
}
@Override
public void swim() {
System.out.println("正在游泳");
}
}
//实现
public class Test {
public static void walk(IRunning running){
System.out.println("我们在散步");
running.run();
}
public static void main(String[] args) {
Cat cat = new Cat("小猫咪");
walk(cat);
}
}
2.6接口间的继承
interface IA {
void run();
}
interface IS {
void swim();
}
//一个接口去继承两个接口
interface IAmphibious extends IA, IS {
}
//再用一个类引用这个接口
class Frog implements IAmphibious {
...
}
2.7Clonable接口和深拷贝
//Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 "拷贝".
//但是要想合法调用 clone 方法, 必须要先实现 Cloneable 接口, 否则就会抛出 CloneNotSupportedException 异常.
//调用Cloneable接口
class Money implements Cloneable{
public double money = 19.9;
//重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
//调用Cloneable接口
class Person implements Cloneable{
public int age = 10;
public Money m = new Money();
//重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
//CLoneable中的clone方法,此时应该强转为Person类型
Person tmp = (Person) super.clone();
//m为Money类型,此时应该强转为Money
tmp.m = (Money) this.m.clone();
return tmp;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
public class test {
public void func() throws CloneNotSupportedException{
Person person = new Person();
//实例化一个person1对象用来克隆person
//由于引用了Cloneable中的方法,因此需要将其强转为Person
Person person1 = (Person) person.clone(); //克隆person对象
//打印修改前的两个money的值
System.out.println(person.m.money);
System.out.println(person1.m.money);
//输出为19.9
// 19.9
System.out.println("===================");
//修改了person1内money的值
//如果是浅拷贝,则会同时修改两个对象的money的值
//深拷贝则修改了person1内money的值
person1.m.money = 99.9;
System.out.println(person.m.money);
System.out.println(person1.m.money);
//输出为19.9
// 99.9
}
public static void main(String[] args) throws CloneNotSupportedException {
test test = new test();
test.func();
}
}
2.8抽象类和接口的区别
核心区别:抽象类中可以包含普通方法和普通字段,这些被继承不必重写,但是接口中不包含普通方法和普通字段,并且其中的抽象方法必须被全部重写.
总结:
![](https://i-blog.csdnimg.cn/blog_migrate/76d9bb48fafe06ae25fe1a80ea256f8d.png)