目录
1.抽象类
1.定义
在面向对象编程中,所有的对象都是用类来描述的,但是不是所有的类都是用来描述对象的。比如抽象类,如果一个类中没有足够的信息来描述对象,那么就把这种类称为抽象类。
一般来说,抽象类专门用来被继承的,有些事物不好用父类完成描述,因此便相当于用抽象类来创建一个模板然后用它的子类来描述对象。
2.语法
用abstract修饰
abstract class Animal{
int age;
String name;
//正常定义属性
//——————————————————————————————————————————
abstract public void func1();
abstract void func2();//没加限定符默认是public
//__________________________抽象方法
//普通方法和构造方法
public void func3() {
}
public Animal(){
}
}
在抽象类中也可以正常定义属性和方法和构造方法;以及定义抽象方法(用abstract修饰的方法)
需要注意的是抽象方法是不允许被定义的,一般用于继承后重写该方法。
3.注意事项
1.抽象类存在的意义就是被用来继承当模板的,因此没有自己定义的方法,所有的抽象方法在被继承后都要重写,除非你也是一个抽象类,比如B继承A(抽象类),B要重写A中所有的抽象方法,如果A也加上abstract就不用,但是如果C继承了B,那么C要重写A和B的抽象方法
2.抽象类是不能实例化的,因为抽象类是一个不能完成描述对象的类,因此我们规定他不能实例化,但是他可以接受他的子类的实例化对象发生向上转型来发生多态
abstract class Animal{
}
class A extends Animal{
}
public class TestDemo1 {
public static void main(String[] args) {
// Animal a = new Animal();//错误
Animal b = new A();
}
}
3.抽象方法不可以被final(代表不可被继承),private(代表不可以被其他类调用)修饰,因为抽象类就是为了继承服务的。
4.抽象类可以没有抽象方法,但是有抽象方法的一定是抽象类
5.抽象类可以有构造方法来帮助一开始的成员初始化。
2.接口
1.定义
java中是没有多继承的概念的,不能A同时继承B,C,因此引申了接口的概念,可以同时继承多个接口来实现相同的功能。
首先要明确一点:接口是一种行为规范,比如生活中的接口,数据线,手机样式千百样但是充电线只有三种,java中的接口也是如此,指的就是一段规范好的代码,可以被其他类使用
2.语法
定义接口的方式与定义类的方式类似
把class改成interface就行了
interface Animal{
int a=0;
public static final int b = 0;
public abstract void fucn1();
public void func2();
abstract void func3();
void func4();
}
接口中的所有属性默认是public static final ,是要有初始值的,所有的方法都是抽象方法
public abstract,定义上可以直接写方法,也可以加上public abstract,编译器默认他们都是抽象方法。
那如果一定要自己定义一个方法,就加上default修饰,但是没什么太多意义,因为接口不能单独使用,也是要被implement(类似继承),同时也不能直接用该接口实例化对象
3.使用接口
interface Animal{
int a=0;
public static final int b = 0;
public abstract void fucn1();
public void func2();
abstract void func3();
void func4();
}
class A implements Animal{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public void fucn1() {
}
@Override
public void func2() {
}
@Override
public void func3() {
}
@Override
public void func4() {
}
}
public class TestDemo1 {
public static void main(String[] args) {
}
}
这里定义了接口Animal,然后定义类A使用该接口,用implement修饰 class A implements Animal
然后要重写所有的抽象方法
注意是先继承在使用接口
eg: class A extends B implement C,D
4.接口使用的例子
我们用自定义的类型Student来创建一个数组arr,此时不能使用Arrays.sort(arr)来排序
仔细看报错信息他说是类Student不能转换成compable导致的错误,其实就是他调用Arrays.sort()
的时候,他会强制把Student实例出来的对象转换成comparable的类型,然后用这个comparable比较方法,这时候我们就要自己调用这个接口(comparable),然后重写这个比较方法来进行比较
下面是代码,首先是定义类Student使用接口comparable,然后重写了该接口里面的比较方法
也就是 compareTo ,后面用到类Student都可以使用该方法,具体的实现底层细节编译器帮我们处理好了。
class Student implements Comparable<Student>{
int age;
String name;
@Override
public int compareTo(Student o) {
return o.name.compareTo(this.name); //不用理解具体的实现细节,这是用c,c++代码写好
//被封装在底层不被用户看到的代码,我们只用在此
//基础调用,返回的是两者相减的结果,后续细节是
//底层代码实现的结果,比如看到返回正数就调换等
//等
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() { //重写打印的方法,便于观察,快捷键是右键generator没然后
//找到toString
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class TestDemo1 {
public static void main(String[] args) {
Student []arr = new Student[3];
arr[0] = new Student(19,"aaaaaa");
arr[1] = new Student(16,"cccccc");
arr[2] = new Student(20,"bbbbbb");
System.out.println("排序前:"+ Arrays.toString(arr));
Arrays.sort(arr);
System.out.println("排序后:"+ Arrays.toString(arr));
}
}