抽象类
//抽象类
abstract class Dog{
public abstract void func();
//抽象方法必须搭配抽象类
}
1.抽象类不能够实例化,可以定义简单的成员变量,成员方法等等,唯一和普通类不一样的加上不能实例化。
2.抽象类虽然不能被实例化,但是可以被继承。抽象类就是为了被继承才存在的。
3.当一个普通类继承了抽象类时,如果这个抽象类包含抽象方法,则需要重写抽象方法,否则报错。
4.如果是一个抽象类继承了另一个抽象类,可以写也可以不重写抽象类的抽象方法。
5.抽象方法不能是private和static以及final。
接口
1.使用interface来表明是一个接口
2.接口当中的成员变量默认都是public static final修饰的。
3.接口当中的成员方法默认都是抽象方法,public abstract修饰的。
interface Tail{
public int a =10;
public final int b =5;
public static final int c =1;
void body();
default void body1(){
};
public abstract void shake();
}
public class test {
}
4.接口当中的普通方法是不能有具体实现的,如果想让他有具体实现,需要在方法前加default,这个特性从JDK8才开始有的。加了default后,调用接口就会默认调用方法了。
5.接口中可以有静态的成员方法,但是不管是静态的还是default的方法,都是由public修饰的。
6.接口不能进行实例化。
7.一个抽象类实现一个接口,可以不重写这个抽象方法,但是当这个抽象类再次被继承,还是要重写。
8.用implements来关联类,然后重写抽象方法,否则报错。
如下:
interface Tail{
public int a =10;
public final int b =5;
public static final int c =1;
void body();
default void body1(){
};
public abstract void shake();
}
class Cat implements Tail{
public void body(){
System.out.println("摇尾巴");
}
public void body1(){
}
public void shake(){
}
}
其实我们可以直接创建一个接口:
然后选择interface 。
接口命名时,一般以大写字母I开头,接口中的方法和属性不要加仍和的修饰符号(public,private)的修饰符号,以保持代码的简洁性。
接口中不能有静态代码块和实例代码块以及构造方法。
接口的继承
interface Itail{
void func();
}
interface Imouse{
void funcB();
}
interface Ihand extends Imouse,Itail{
void funcC();
}
class T implements Ihand{
@Override
public void func() {
}
@Override
public void funcB() {
}
@Override
public void funcC() {
}
}
被继承的接口被类引用后,需要重写全部的接口的方法。
几个重要的接口
compareTo接口
public class L521 {
public static void main(String[] args) {
Student student1 = new Student("李",11,66.6);
Student student2 = new Student("王",11,88.8);
//如何比较这两个对象的大小?
if(student1.compareTo(student2)>0){
System.out.println("student1>student2");
}
if(student1.compareTo(student2)<0){
System.out.println("student1<student2");
}
else {
System.out.println("student1=studnet2");
}
}
}
class Student implements Comparable<Student>{
public String name;
public int age;
public double score;
//然后重写compare to方法
@Override
public int compareTo(Student o) {
//o就是调用的参数,谁调用compareTo谁就是this
if(this.age>o.age){
return 1;
}
else if(this.age==o.age){
return 0;
}
else {
return -1;
}
}
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
当我们要对数据进行排序时也是同理,需要先重写compareTo去告诉用什么来排序
//main里面
Student student[] =new Student[3];
student[0]=new Student("红",1,4);
student[1]=new Student("绿",2,5);
student[2]=new Student("蓝",3,6);
System.out.println("排序前"+ Arrays.toString(student));
Arrays.sort(student);
System.out.println("排序后"+ Arrays.toString(student));
//Arrays.sort(student,agecompare);
//arrays还可以传递第二个参数,来指导用什么比较。
comparator接口(比较器)
class Agecompare implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.age-o2.age;
}
}
cloneable接口(克隆)
首先实现一个cloneable接口
class Person implements Cloneable{
public int age = 0;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
//调用object类来进行克隆
}
}
public class L521 {
public static void main(String[] args) throws CloneNotSupportedException {
//通过alt+enter来抛出异常。
Person person = new Person();
//将clone的返回类型设置成peeson类型
Person person2=(Person) person.clone();
}
}
以上就完成了对象的克隆。产生了对象的副本。
深拷贝问题
class Person implements Cloneable{
public int age = 0;
public Money m = new Money();
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
//调用object类来进行克隆
}
}
class Money{
public double money = 9.9;
}
public class L521 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
Person person2=(Person) person.clone();
person2.m.money=99.9;
System.out.println(person.m.money);
System.out.println(person2.m.money);
}
}
是浅拷贝,因为只拷贝了这个对象,而没有拷贝这个对象引用所指向的对象。所以最后原本和副本都改变了。
深拷贝则需要:
class Money implements Cloneable{
public double money = 9.9;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
在money类里实现cloneable接口后并重写方法
class Person implements Cloneable{
public int age = 0;
public Money m = new Money();
@Override
protected Object clone() throws CloneNotSupportedException {
Person tmp = (Person) super.clone();
tmp.m=(Money) this.m.clone();
return tmp;
//调用object类来进行克隆
}
}
class Money implements Cloneable{
public double money = 9.9;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
在person里面使用tmp来储存一份拷贝,以此达到深拷贝。