抽象类
abstract class Animal{
abstract public void cry(); //抽象方法不实现
//抽象类中可以有非抽象方法
public void fun1()
{
System.out.println("Animal fun1");
}
}
//当一个类实现某个抽象类的时候,必须实现其抽象方法
class Dog extends Animal{
public void cry()
{
System.out.println("旺旺");
}
}
//如果一个抽象类继承一个抽象类,那么可以不实现基类的抽象方法
abstract class Cat extends Animal{
}
class LittleCat extends Cat{
//当你继承的抽象类有父类的时候,你也必须实现其父类的抽象方法
@Override
public void cry() {
// TODO Auto-generated method stub
}
}
从上面的代码我们可以看出抽象类的大部分特点
除了上面的还有
1.抽象类不能实例化(不能new)
2.抽象类中的默认修饰符为public
3.子类必须实现抽象父类的抽象方法,如果不实现子类必须由abstract修饰(即子类必须为抽象类)
密封类
密封类及被final
修饰的类,其不能被继承,而且方法不能被修改
其主要是为了防止派生。
接口
接口的作用主要是因为Java不具备多继承所以通过接口可以进行各种方法的继承。一个类可以同时实现多个接口。
1.接口中默认数据成员为 public static final
默认成员方法为 public abstract
2.接口和接口直接可以继承
interface A extends B{}
,相当于A扩展B
3.接口不能实现接口
Demo:
//接口A
interface A {
public int age = 10;
public void fun1();
}
//接口B
interface B{
int b = 100;
void fun2();
}
//类C实现接口A和B
class C implements A,B{
//因为其实现了这两个接口,所以需要实现其中的所有方法
@Override
public void fun2() {
// TODO Auto-generated method stub
}
@Override
public void fun1() {
// TODO Auto-generated method stub
}
}
接口和抽象类的区别
1.接口可以被实现多个,抽象类只能继承一个
2.抽象类中可以写非抽象方法
3.接口的数据成员变量都是public static final
4.接口是对行为的一种抽象(如鸟会飞,飞机会飞,飞就是接口),抽象类本身是对类整体的抽象(猫是动物,狗也是动物,动物就是抽象类)
接口的应用
1.Cloneable
class Money implements Cloneable{
double money = 10.0;
@Override
protected Object clone() throws CloneNotSupportedException {
Money m = (Money) super.clone();
return m;
}
}
//Cloneable 空接口
//Cloneable 标志位 flag 如果不实现 JVM无法识别
class Person implements Cloneable{
public String name;
Money m;
public Person(String name) {
this.name = name;
m = new Money();
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person p = (Person) super.clone();
p.m = (Money)this.m.clone();
return p;
}
}
Cloneable接口主要是为了类的克隆,这样的话你的类就具有了克隆的方法,就可以通过.clone
调用克隆方法,然后进行类的克隆。
测试
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person("li1");
Person p2 = (Person) p1.clone();
System.err.println("p1"+p1);
System.err.println("p2"+p2);
p1.m.money = 1000;
System.err.println(p1.m.money);
System.err.println(p2.m.money);
}
结果
p1time20180523.Person@1d7fbfb
p2time20180523.Person@e020c9
1000.0
10.0
可以看出其打印出来的地址不同。
注意
此接口在使用的时候,clone
方法和Cloneable
必须同时使用,不可单独使用,如果单独使用就会报异常,因为JVM(Java虚拟机)需要一个接口当做标志位,来判别其是否可以被克隆。
2. Comparable
此接口主要是用于比较。
class Person1 implements Comparable<Person1>{
private String name;
private int age;
private double score;
public Person1(String name, int age, double score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
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 double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "Person1 [name=" + name + ", age=" + age + ", score=" + score + "]";
}
@Override
/**
* o为待排序的
*/
public int compareTo(Person1 o) {
//按年龄降序
return o.age-age;
}
}
在类实现此接口之后就可以调用系统的排序函数进行排序。
测试
public static void main(String[] args) {
Person1[] array = new Person1[3];
array[0] = new Person1("one", 10, 3);
array[1] = new Person1("two", 26, 2);
array[2] = new Person1("three", 3, 1);
Arrays.sort(array);
System.out.println(Arrays.toString(array));
}
结果[Person1 [name=two, age=26, score=2.0], Person1 [name=one, age=10, score=3.0], Person1 [name=three, age=3, score=1.0]]
在Arrays.sort函数中
此函数 就是为了进行对象排序所准备的。
3.Comparator
Comparator为比较器,其比Comparable灵活,使用方式为
public static void main(String[] args) {
Person1[] array = new Person1[3];
array[0] = new Person1("one", 10, 3);
array[1] = new Person1("two", 26, 2);
array[2] = new Person1("three", 3, 1);
//按照用户自己的想法进行排序
Arrays.sort(array,new Comparator<Person1>() {
@Override
public int compare(Person1 o1, Person1 o2) {
//按照年龄排序
return (int) (o1.getAge()-o2.getAge());
}
});
System.out.println(Arrays.toString(array));
Arrays.sort(array,new Comparator<Person1>() {
@Override
public int compare(Person1 o1, Person1 o2) {
//按照成绩排序
return (int) (o1.getScore()-o2.getScore());
}
});
System.out.println(Arrays.toString(array));
}
可以看出来其运用了匿名内部类构建compare接口,在其内部实现排序的对比。
结果
[Person1 [name=three, age=3, score=1.0], Person1 [name=one, age=10, score=3.0], Person1 [name=two, age=26, score=2.0]]
[Person1 [name=three, age=3, score=1.0], Person1 [name=two, age=26, score=2.0], Person1 [name=one, age=10, score=3.0]]