抽象类
- 包含抽象方法的类,叫做抽象类。
- 抽象方法:由abstract所修饰,而且,类也需要由abstract所修饰。
- 抽象方法:在抽象类内部不给于实现。
- 抽象方法不能被private所修饰,如果不加访问修饰限定符,那么默认为public
当有一个类,继承了当前的抽象类后,需要实现。
a、抽象类中:可以有非抽象方法;
b、抽象类不能创建实例对象(new对象);
“抽象类是对部分的方法进行抽象”
abstract class Animal{
public abstract void bark(); 抽象方法:抽象类中的不予以实现.
public void fun(){
System.out.println("abstract Animal fun()");//普通方法要进行实现
}
}
- 抽象类的派生类
1、如果是普通类,那么必须实现抽象类的抽象方法
2、如果是抽象类,那么可以不实现基类的抽象方法
1、派生类为普通类
class Dog extends Animal{
public Dog(){ //不带参数的构造方法
System.out.println("Dog() init");
}
public void bark(){
System.out.println("Dog:wangwang");
}
}
public class Test1031 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.bark();
}
}
运行结果:
Dog() init
Dog:wangwang
2、派生类为抽象类
abstract class Dog extends Animal{
public Dog(){ //不带参数的构造方法
System.out.println("Dog() init");
}
//不实现基类的抽象方法
面试问题
- 抽象类的普通类的区别?
1、抽象类不能被实例化;
2、抽象方法必须是public或者protected访问限定修饰符,或者不写;
3、抽象类被abstract所修饰;
4、抽象方法不能在抽象类中实现;
abstract class Animal{
public abstract void bark();
}
密封类
- 当一个类,被final所修饰时,称为密封类。
final class Person1{
private String name;
private int age;
public Person1(){
System.out.println("Person1 init()");
}
public void fun1(){
System.out.println("Person1 init()");
}
}
- 注意:
1、密封类不能作用于基类。
2、就算派生类也被final所修饰也不可以。
final class Student extends Person1{
}
- 密封方法=====》不能被重写
public final void fun1(){
System.out.println("Person1 init()");
}
- 作用:防止有意的派生
接口
- 接口:由interfacr定义
- 属性:默认为: public static final
- 方法:默认为:public abstract
interface A{
public static final int age = 10;
public abstract void fun();
}
在Java里,继承只是单继承---------》接口实现多继承,解决单继承局限问题
- impletements 实现接口 接口之间用“,”隔开。
- 注意:
1、接口内的方法,必须不能被实现,而抽象类可以有部分非抽象方法。
2、一个抽象类只可以继承一个父类,但是一个接口可以使用关键字extends继承多个接口。
3、抽象类是对类整体的抽象,而接口是对行为进行抽象。
4、抽象类当中的方法和成员变量没有明确要求,但是抽象类中的方法不能是私有的。
接口的实现
* FIRST
interface A{
public static final int AGE = 10;
public abstract void fun();
}
interface B {
int AGE = 100;
void fun();
}
class C implements A,B{ // c 实现接口 A,B 必须实现方法
public void fun(){
System.out.println("A.FUN()"); //实现方法
}
public void fun2(){
System.out.println("B.FUN()"); //实现方法
}
}
public class TEST0311 {
public static void main(String[] args) {
C c = new C();
c.fun();
c.fun2();
运行结果:
A.FUN()
B.FUN()
* SECOND
public static void main(String[] args) {
C c = new C();
A a = c;
a.fun();
B b = c;
c.fun2();
}
运行结果:
A.FUN()
B.FUN()
- 小结
1、在java中,继承只是单继承
2、implements 实现接口 接口之间用“,”隔开,{}中必须写实现的接口中的方法 。
接口的实现
interface A{
public static final int AGE = 10;
public abstract void fun();
}
interface B {
int AGE = 100;
void fun();
}
interface D extends A,B{
void fun3();
- 注意
interface D extends A,B{ // {}内可以不实现继承的接口的内容(不用写出来在{}中)
void fun3();
//D中有三个方法,A中的fun() B中的fun2() D中的fun3()方法
}
例子:门和报警器 (门:open close 报警器:报警功能alarm)
abstract class Door {
public abstract void open();
public abstract void close();
}
interface Alarm{
public abstract void alarm();
}
abstract class AlarmDoor extends Door implements Alarm { //报警门 继承了门的open和close的功能,并且实现了报警的功能
@Override
public void open() {
}
@Override
public void close() {
}
@Override
public void alarm() {
}
}
四个接口
- Clonable
- Comparable
- Comparator
- ====>Interable/Iterator
Cloneable
class Money{
double money = 20.0;
}
//克隆自定义类,必须实现一个Cloneable接口
class Person2 implements Cloneable{
private String name;
Money m;
public Person2(String name){
this.name = name;
this.m = new Money();
}
//重写Object
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); //调用基类克隆方法
}
}
public class Test10312 {
public static void main(String[] args) throws CloneNotSupportedException {
Person2 person2 = new Person2(" caocao");
Person2 person21 = (Person2) person2.clone(); // 强制转换 基类引用派生类对象浅拷贝
System.out.println(person2.m.money);
System.out.println(person21.m.money);
System.out.println("==============");
person2.m.money = 1000.0; //改person2的值
//改完输出
System.out.println(person2.m.money);
System.out.println(person21.m.money);
}
} //浅拷贝
运行结果:
20.0
20.0
==============
1000.0
1000.0
class Money implements Cloneable{ //深拷贝 实现Cloneable的接口
double money = 20.0;
//重写基类的克隆方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
//克隆自定义类,必须实现一个Cloneable接口
class Person2 implements Cloneable{
private String name;
Money m;
public Person2(String name){
this.name = name;
this.m = new Money();
}
//重写Object类的克隆方法 Ctrl+o
@Override
protected Object clone() throws CloneNotSupportedException {
Person2 person2 = (Person2)super.clone(); // 强制转换
person2.m = (Money)this.m.clone();
return person2;
}
}
public class Test10312 {
public static void main(String[] args) throws CloneNotSupportedException { //添加异常CloneNotSupportedException
Person2 person2 = new Person2(" caocao");
Person2 person21 = (Person2) person2.clone(); // 强制转换 基类引用派生类对象浅拷贝
System.out.println(person2.m.money);
System.out.println(person21.m.money);
System.out.println("==============");
person2.m.money = 1000.0; //改money的值 浅拷贝
//改完输出
System.out.println(person2.m.money);
System.out.println(person21.m.money);
}
}
运行结果:
20.0
20.0
==============
1000.0
20.0
//深拷贝
Clonable接口
- 实现Clonable接口,并且需要重写Object的clone方法。
- 面试问题;public interface Cloneable{ }是个空接口(标记接口),这个空接口的设计有什么作用?
它是标记当前这个类可以进行clone,如果不实现这个接口JVM不能识别。
Comparable接口
class Student implements Comparable<Student>{
private String name;
private int age;
private double score;
public Student(String name, int age, double score){
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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
@Override
public int compareTo(Student o) {
return name.compareTo(o.name); //根据姓名排序
return age - o.age; //根据年龄排序
}
}
public class Test10313 {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("gaobo",48 ,99.0 );
students[1] = new Student("awangzhuo",28 ,49.0 );
students[2] = new Student("gaobo",18 ,59.9 );
}
}
运行结果:
[Student{name='gaobo', age=18, score=59.9}, Student{name='wangzhuo', age=28, score=49.0}, Student{name='gaobo', age=48, score=99.0}]
-
Comparable接口 public interface Comparable(
-
public int comparaTo(T o);
-
class Student implements Comparable {}
-
@Override
public int compareTo(Student o) {return name.compareTo(o.name);
// return age - o.age;
}
Comparator
class Student implements Comparable<Student> {
private String name;
private int age;
private double score;
public Student(String name, int age, double score){
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 "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
@Override
public int compareTo(Student o) {
return name.compareTo(o.name); //根据姓名排序
// return age - o.age; //根据年龄排序
}
}
public class Test10313 {
public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("gaobo",48 ,99.0 );
students[1] = new Student("wangzhuo",28 ,49.0 );
students[2] = new Student("qinpanpan",18 ,59.9 );
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// return o1.getAge()-o2.getAge();
return (int )(o1.getScore() - o2.getScore());
// return o1.getName().compareTo(o2.getName()); }
});
System.out.println(Arrays.toString(students));
//接口在Arrays.sort() 排序时可以new
}
运行结果:
[Student{name='wangzhuo', age=28, score=49.0}, Student{name='qinpanpan', age=18, score=59.9}, Student{name='gaobo', age=48, score=99.0}]
- 面试问题:Comparable和Comparator的区别?
- Comparable 作用于类内部
- Comparator 作用于类内部
- 源码层次上:
- Comparator 类内部是int compare(T o1, T o2);
- Comparable 类内部是 public int compareTo(T o);