目录
抽象类
接口
接口
接口的实现类
三个常用接口
comparable
comparator
cloneable接口
深浅拷贝
抽象类
抽象方法:一个没有具体实现的方法,被abstract关键字修饰
关键类:包含抽象方法的类
abstract class Draw{ public abstract void draw() ; }
抽象方法不能有主体
抽象方法不能实例化
抽象类中可以包括普通成员
abstract class Draw{ int age; String name; public void print() { System.out.println("hi"); } public abstract void draw() ; }
抽象类只能被继承,子类必须重写父类里的所有抽象方法(子类如果是抽象类,可以只实现一部分)
abstract class Draw { public abstract void draw(); } class Fun extends Draw{ @Override public void draw() { System.out.println("hehe"); } } public class text { public static void main(String[] args) { Fun fun=new Fun(); fun.draw(); } }
Fun类继承了这个抽象类,并且对这个抽象类的抽象方法进行了重写,实例化子类调用子类中重写的方法
抽象类也可以发生向上转型和动态绑定
abstract class Draw { public abstract void draw(); } class Flower extends Draw{ @Override public void draw(){ System.out.println("❀"); } } class Square extends Draw{ @Override public void draw(){ System.out.println("■"); } } class Triangle extends Draw{ @Override public void draw(){ System.out.println(""); } } public class text { public static void Draw(Draw Draw) { Draw.draw(); } public static void main(String[] args) { Draw(new Flower()); Draw(new Square()); Draw(new Triangle()); } }
抽象类不能被final修饰
final类是最终类,被final修饰的类不能被继承,而抽象类的作用就是被继承
接口 接口如果一个类中全部的方法都是抽象的,那么可以将这个类定义为接口
接口是一种特殊的抽象类,它不能包含普通方法,其内部的所有方法都是抽象的
JDK8中,对接口进行了重新定义,接口中除了抽象方法外,还可以有默认方法和静态方法,默认方法使用default修饰,静态方法用static修饰,并且这两个方法都允许有方法体
定义接口,要用interface关键字
interface AI{ public abstract void fun(); }
interface AI{ public abstract void fun(); default public void print(){//默认方法 System.out.println("hi"); } public static void sub(){//静态方法 } }
接口里的所有方法都是public的接口不可以使用new来创建对象接口内部有3种方法,抽象方法,静态方法,默认方法借口内部的成员变量默认类型:public static final,一定要初始化
静态方法可以通过接口名.静态方法名来调用
interface AI{ public abstract void fun(); default public void print(){ System.out.println("hi"); } public static void sub(){ System.out.println("ok"); } } public class text { public static void main(String[] args) { AI.sub(); } }
默认方法和抽象方法要通过类的实例化调用
接口的实现类接口的实现类通过implements关键字实现当前接口,并重写接口的所有抽象方法
interface AI{ public abstract void fun(); default public void print(){ System.out.println("hi"); } public static void sub(){ System.out.println("ok"); } } class A implements AI{ @Override public void fun() { System.out.println("❀"); } } public class text { public static void main(String[] args) { A a=new A(); a.fun(); } }
A类实现了AI口,并对AI接口的抽象方法进行了重写,通过对A类的实例化对象可以引用AI接口的成员(除了静态方法)
1.一个类可以实现多个接口
interface AI{ public abstract void funA(); } interface BI{ public abstract void funB(); } class A implements AI,BI{ @Override public void funA() { System.out.println("❀AI"); } @Override public void funB() { System.out.println("❀BI"); } }
A类继承了AI,BI接口,要对AI,BI的所有抽象方法进行重写
2.一个类可以继承一个类同时实现多个接口
interface AI{ public abstract void funA(); } interface BI{ public abstract void funB(); } abstract class B{ abstract void fun(); } class A extends B implements AI,BI{ @Override public void funA() { System.out.println("❀AI"); } @Override public void funB() { System.out.println("❀BI"); } @Override void fun() { System.out.println("hi"); } }
A类继承了抽象类B,并继承了AI,BI接口,要对B,AI,BI的所有抽象方法进行重写
3.接口可以扩展一个接口(extends)
interface AI{ public abstract void funA(); } interface BI extends AI{ public abstract void funB(); } class C implements BI{ @Override public void funB() { } @Override public void funA() { } }
BI接口扩展了AI接口,那么BI接口就会包含了AI接口的成员,C类继承了BI接口,要对BI接口的所有抽象方法重写
三个常用接口 comparablepublic class text { public static void main(String[] args) { int[] arr = {1, 2, 3, 1}; System.out.println(Arrays.toString(arr)); Arrays.sort(arr); System.out.println(Arrays.toString(arr)); } }
sort方法实现了数组排序
class Student { int age; String name; public Student(int age,String name) { this.age = age; this.name = name; } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + ''' + '}'; } } public class text { public static void main(String[] args) { Student []student=new Student[3]; student [0]=new Student(10,"张三"); student [1]=new Student(9,"李四"); student [2]=new Student(3,"王五"); System.out.println(Arrays.toString(student)); Arrays.sort(student); System.out.println(Arrays.toString(student)); }
报错原因:不知道按照什么条件来排序
sort方法的源码:发现数组元素被强制转化为comparable
如何解决:
使用Comparable接口:让类实现这个接口
进入Comparable接口
那么正确的实现方法:
实现这个接口并对public int compareTo(T o)方法重写
@Override public int compareTo(Student o) { if (this.age > o.age) { return 1; } else if (this.age == o.age) return 0; else return -1; } // return this.age-o.age;可以简化 }
根据年龄比较:
根据姓名比较:如果使用equals方法, 字符串比较返回值boolean类型,不能强制转化为int
打开String 的源码:
发现String也调用了这个接口,那么也一定有compareTo(T o)方法,Alt+7找到这个方法:
调用这个方法就可以来比较了
class Student implements Comparable{ int age; String name; public Student(int age, String name) { this.age = age; this.name = name; } @Override public int compareTo(Student o) { return this.name.compareTo(o.name); } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + ''' + '}'; } } public class text { public static void main(String[] args) { Student[] student = new Student[3]; student[0] = new Student(10, "张三"); student[1] = new Student(3, "王五"); student[2] = new Student(9, "李四"); System.out.println(Arrays.toString(student)); Arrays.sort(student); System.out.println(Arrays.toString(student)); }
但是我们发现,用这个接口,要重写 compareTo()方法,但是这个方法只能有一个,只能按照一种办法来比较,使用comparator接口可以实现多种比较
comparatorsort有许多种参数不同的实现方法,可以看到其中有一个方法参数是comparator
打开comparator这个接口
使用comparator接口可以实现多种比较
class Student { int age; String name; public Student(int age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + ''' + '}'; } } class AgeComparator implements Comparatorcloneable接口{//类实现了接口 @Override public int compare(Student o1, Student o2) { return o1.age-o2.age; } } class NameComparator implements Comparator {//类实现了接口 @Override public int compare(Student o1, Student o2) { return o1.name.compareTo(o2.name); } } public class text { public static void main(String[] args) { Student[] student = new Student[3]; student[0] = new Student(10, "张三"); student[1] = new Student(3, "王五"); student[2] = new Student(9, "李四"); System.out.println(Arrays.toString(student)); AgeComparator ageComparator = new AgeComparator();//实例化类 按照年龄比较 Arrays.sort(student, ageComparator);//传入参数有两个 System.out.println(Arrays.toString(student)); Arrays.sort(student, new NameComparator()); System.out.println(Arrays.toString(student)); }
object类有一个clone方法,使用这个方法可以进行拷贝,但是要调用这个方法,要先实现cloneable接口,否则会报错
打开clone方法
发现clone()的返回值类型是object,所以进行强制类型转化
但是仍然有错误,必须实现cloneable接口
打开cloneable接口
cloneable接口内没有方法体,不需要对接口的内部方法进行重写
没有方法体的接口称之为标志接口,标志接口代表当前这个类是可以被克隆的
但是规定:要求在类中重写clone方法
class Person implements Cloneable{ int age; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
但是这时候发现,仍然有问题:
点击以下内容,对异常进行声明:
class Person implements Cloneable{ int age; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class text { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); Person p=(Person) person.clone(); } }深浅拷贝
代码1:
class Person implements Cloneable{ int age=9; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class text { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); System.out.println(person); Person p=(Person) person.clone(); System.out.println(p); p.age=109; System.out.println(person.age); System.out.println(p.age); System.out.println(person.age); } }
对person引用的对象的成员信息拷贝之后产生一个副本,p引用了这个新的对象,所以person和p的地址不相同 ,对p的成员改变不会影响person的成员
代码2:
class A{ int s=78; } class Person implements Cloneable{ int age=9; A a=new A(); @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class text { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); Person p=(Person) person.clone(); System.out.println(p.a); System.out.println(person.a); }
对person引用的对象的成员信息拷贝之后产生一个副本,p引用了这个新的对象,所以person和p的地址不相同
但是因为person引用的对象中,有一个引用成员变量a,现在的代码导致产生的副本和person引用的成员中的变量a,引用了同一个对象
这是一个浅拷贝
代码3:
class A implements Cloneable{ int s=78; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable{ int age=9; A a=new A(); @Override protected Object clone() throws CloneNotSupportedException { Person p = (Person) super.clone();//先对person克隆 p.a = (A) a.clone();//对person中a的克隆 return p; } } public class text { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); Person p=(Person) person.clone(); System.out.println(p); System.out.println(person); System.out.println(p.a); System.out.println(person.a); System.out.println(p.a.s); System.out.println(person.a.s); p.a.s=90; System.out.println(p.a.s); System.out.println(person.a.s); } }
对person和a两个引用变量都进行了拷贝
这是一个深拷贝
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)