抽象类
1.包含抽象方法的类,叫做抽象类。由abstract修饰。
2.抽象类当中:可以有非抽象方法。
3.抽象类不能创建实例对象。
抽象方法
1.在抽象类内部不给予实现。当有一个类,继承了当前的抽象类后,需要实现。
2.抽象方法不能被private修饰,如果不加访问修饰限定符,默认为public。
抽象类的派生类
1.如果是普通类,那么必须实现抽象类的抽象方法。
2.如果是抽象类,可以不实现基类的抽象方法。
抽象类和普通类的区别
1、抽象类不能被实例化。
2、抽象方法不能被private修饰。
3、抽象类被abstract修饰。
4、抽象方法不能在抽象类当中实现。
如下代码为抽象类的例子:
abstract class Animals {
public abstract void bark();
}
//派生类为普通类,必须实现基类的抽象方法
class Cat extends Animals {
public void bark() {
System.out.println("Cat:喵~~喵~~喵~~");
}
}
class Dog extends Animals {
public void bark() {
System.out.println("Dog:汪~~汪~~汪~~");
}
}
//派生类为抽象类,可以不实现基类的抽象方法
abstract class Pig extends Animals {
public void fun() {
System.out.println("abstract class Pig:fun()");
}
}
public class TestDemo5 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.bark();//Dog:汪~~汪~~汪~~
Cat cat = new Cat();
cat.bark();//Cat:喵~~喵~~喵~~
}
}
如下代码为密封类的例子:
final class Student {
private String grade;
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
接口由interface定义
属性默认修饰符为public static final
方法默认修饰符为public abstract
如:
interface One {
public static final int COUNT = 1;//修饰符为默认的,只写int COUNT即可
public abstract void methods1();
}
1.接口内的方法,必须不能被实现,而抽象类可以存在非抽象方法。
2.抽象类只能继承一次,但是接口可以被实现或者继承多个。
a. 一个抽象类可以继承一个抽象父类,但是一个接口可以使用关键字
extends继承多个接口
b. 抽象类是对类整体的抽象 而接口是对行为(方法)进行抽象
c. 接口中的成员变量和成员方法默认为public static final
和public abstract
d. 抽象类当中的方法和成员变量的修饰符没有明确要求,但是抽象类当中的
方法不能用private修饰。
interface One {
public static final int COUNT = 1;
public abstract void methods1();
}
interface Two {
void methods2();
}
//这样写新的接口可以不实现extends后接口的方法
interface Three extends One, Two {
void methods3();
}
//实现接口Three
class Test implements Three {
public void methods1() {
System.out.println("One.methods1()");
}
public void methods2() {
System.out.println("Two.methods2()");
}
public void methods3() {
System.out.println("Three.methods3()");
}
}
public class TestDemo5 {
public static void main(String[] args) {
Test test = new Test();
test.methods1();//One.methods1()
test.methods2();//Two.methods2()
test.methods3();//Three.methods3()
One one = test;
one.methods1();//One.methods1()
Two two = test;
two.methods2();//Two.methods2()
Three three = test;
three.methods3();//Three.methods3()
}
}
在类外实现 int compare(T o1, T o2)方法
class Teacher {
private int id;
private String subject;
private String name;
public Teacher(int id, String subject, String name) {
this.id = id;
this.subject = subject;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", subject='" + subject + '\'' +
", name='" + name + '\'' +
'}';
}
}
public class TestDemo4 {
public static void main(String[] args) {
Teacher[] teacher = new Teacher[3];
teacher[0] = new Teacher(04, "History", "H.s");
teacher[1] = new Teacher(02, "Math", "M.a");
teacher[2] = new Teacher(03, "English", "E.n");
System.out.println(Arrays.toString(teacher));
System.out.println("========按姓名排序=========");
Arrays.sort(teacher, new Comparator<Teacher>() {
@Override
public int compare(Teacher aa, Teacher bb) {
return aa.getName().compareTo(bb.getName());
}
});
System.out.println(Arrays.toString(teacher));
System.out.println("========按id排序=========");
Arrays.sort(teacher, new Comparator<Teacher>() {
@Override
public int compare(Teacher aa, Teacher bb) {
return (aa.getId() - bb.getId());
}
});
System.out.println(Arrays.toString(teacher));
}
}
在类内实现compareTo(T o)方法
class Teacher implements Comparable <Teacher>{
private int id;
private String subject;
private String name;
public Teacher(int id, String subject, String name) {
this.id = id;
this.subject = subject;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", subject='" + subject + '\'' +
", name='" + name + '\'' +
'}';
}
@Override
public int compareTo(Teacher aa) {
return subject.compareTo(aa.subject);
}
}
public class TestDemo4 {
public static void main(String[] args) {
Teacher[] teacher = new Teacher[3];
teacher[0] = new Teacher(04, "History", "H.s");
teacher[1] = new Teacher(02, "Math", "M.a");
teacher[2] = new Teacher(03, "English", "E.n");
Arrays.sort(teacher);
System.out.println(Arrays.toString(teacher));
}
}
public interface Cloneable {
}
此接口在源代码中为空接口,空接口的作用是标记这个类可以进行clone,如果不实现这个接口JVM不能够识别。
实例:
class Color implements Cloneable {
String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Size implements Cloneable {
Color color;
public Size() {
this.color = new Color();
}
//重写Object的克隆方法
@Override
protected Object clone() throws CloneNotSupportedException {
Size size = (Size) super.clone();
size.color = (Color) this.color.clone();
return size;
}
}
public class TestDemo4 {
public static void main(String[] args) throws CloneNotSupportedException {
Size size = new Size();
Size size1 = (Size) size.clone();
System.out.println(size.color.name);
System.out.println(size1.color.name);
size1.color.name = "red";
System.out.println(size.color.name);
System.out.println(size1.color.name);
}
}
这种clone方法为深拷贝,原因如下:
在重写的clone()方法中有以下两条语句:
Size size = (Size) super.clone();
size.color = (Color) this.color.clone();
在例子中的代码中,第一条语句将size中的元素全部克隆到了size1中,但是Size类中只有指向Color的color,所以此时两者指向的地址相同
第二条语句将color指向的地址也同样复制了,所以size和size1中元素就会指向两个地址,即深拷贝,下面的图可以辅助理解