提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
1.调用compareable接口,重写其中的compare to方法
总结:
回顾javase基础
提示:以下是本篇文章正文内容,下面案例可供参考
1.使用abstract修饰的方法是抽象方法
2.包含抽象方法的类必须设计为抽象类,使用abstract修饰这个类

3.抽象类是不能够被实例化的

4.抽象类当中,可以有和普通类一样的方法,成员,最突出的和普通类不一样的地方是,抽象类不可以进行实例化
- public abstract class Shape {
- public int a;
- public int b;
- public void fun(){
-
- }
- //抽象方法
- public abstract void draw();
- }
5.抽象类虽然不可以进行实例化,但是可以被继承,也就是说抽象类其实就是为了被继承
6.当一个普通l类继承这个抽象类之后,如果这个抽象类当中包含抽象方法,那么需要重写这个抽象方法,否则代码不能通过编译(相当于编译器的一层检查必须如果是重写抽向方法必须加上@override)
-
- class Rect extends Shape{
- @Override
- public void draw() {
- System.out.println("重写抽象方法");
- }
- }
7.如果一个抽象类a继承另一个抽象类b,那么此时抽象类a,可以不重写b的抽象方法(此时实现类要重写所有的抽象方法)
画图形
- package 抽象类和接口;
-
- public abstract class Shape {
- public int a;
- public int b;
- public void fun(){
-
- }
- //抽象方法
- public abstract void draw();
- }
- class Rect extends Shape{
- @Override
- public void draw() {
- System.out.println("重写抽象方法");
- }
- }
- class Flower extends Shape{
- @Override
- public void draw() {
- System.out.println("画一朵花");
- }
- }
- class Cycle extends Shape {
- @Override
- public void draw() {
- System.out.println("圆形");
- }
- }
- class Triangle extends Shape {
- @Override
- public void draw() {
- System.out.println("△");
- }
- }
- package 抽象类和接口;
-
- public class Test {
- public static void darwMap(Shape shape){
- shape.draw();
- }
- public static void main(String[] args) {
- // Shape shape=new Shape();
- darwMap(new Cycle());
- darwMap(new Flower());
- darwMap(new Triangle());
- darwMap(new Rect());
- }
- }
8.抽象方法不能是private的,static,final修饰
9.抽象类也可以有构造方法
1.使用interface修饰一个接口
interface Shape{}
2.接口当中的成员变量默认都是public static final修饰的
3.接口当中的成员方法,默认都是抽象方法,punlic ,abstract修饰的
- //接口当中的方法默认都是被public abstract 修饰
- abstract void fun1();
- public void fun2();
- public abstract void fun();
- void draw();
- //接口当中成员变量默认被public static final修饰
- public static final int a=5;
- public static final int b=7;
4.接口当中的实例成员方法(普通方法)是不能有具体的实现的
![]()
5.接口当中的实例成员方法(普通方法)如果要有具体的实现,必须加上default修饰
default void draw(){};
6.接口当中可以有静态的成员方法,但是不管是静态的方法还是普通方法都是被public修饰的
- public static void fun5(){
- System.out.println("静态方法");
- }
7.接口本身不能被实例化
8.类和接口的关系是使用implements来关联的
- class Rect implements Shape{
- @Override
- public void fun1() {
- System.out.println("重写接口方法");
- }
- }
109.一个接口可以引用具体的实现类的,相当于是向上转型
- public class Test {
- public static void drawMap(Shape shape){
- shape.fun1();
- }
- public static void main(String[] args) {
- Rect rect=new Rect();
- drawMap(rect);
-
- //可以发生向上转型
- Shape shape=new Rect();
- }
- }
10.接口当中不能有静态,实例代码块,构造方法
因为接口不能直接调用,要靠实现类继承
11.一个抽象类实现一个接口,可以不重写这个抽象方法,但是出来混迟早要还。
- abstract class A implements Shape{
- ;
- }
由于我们不清楚eat什么,可以先设置成抽象方法,等待类被继承
- abstract class Animal{
- String name;
- int age;
-
- public Animal(String name, int age) {
- this.name = name;
- this.age = age;
- }
- // public void eat(){
- // System.out.println("动物会干饭");
- // }
- public abstract void eat();
- }
需要重写抽象方法
- class Dog extends Animal{
- public Dog(String name, int age) {
- super(name, age);
- }
- @Override
- public void eat() {
- System.out.println("狗吃狗粮");
- }
- }
重写eat方法:
- class Bird extends Animal{
- public Bird(String name, int age) {
- super(name, age);
- }
- @Override
- public void eat() {
- System.out.println("鸟吃鸟粮");
- }
- }
通过方法传参形式完成向上转型,并调用重写后的方法
- public class Test2 {
- public static void fun(Animal animal){
- animal.eat();
- }
-
- public static void main(String[] args) {
- fun(new Bird("小鸟",15));
- fun(new Dog("二哈",8));
- }
- }
此时还有缺陷:小鸟还会飞,但是动物不一定都会飞,如果给动物类飞设置成抽象方法,后续实现类都需要重写飞的方法,非常麻烦。
如果采取向下转型,如果后续还有要飞的动物,又重写判定也不方便,java还不能多继承,不能在写一个实现类。
这时候就需要考虑接口了
- interface fly{
- public abstract void fly();
- }
- class Bird extends Animal implements fly{
- public Bird(String name, int age) {
- super(name, age);
- }
- @Override
- public void eat() {
- System.out.println("鸟吃鸟粮");
- }
-
- @Override
- public void fly() {
- System.out.println("鸟会飞");
- }
- }
- public class Test2 {
- public static void fly(IFly iFly){
- iFly.fly();
- }
- public static void fun(Animal animal){
- animal.eat();
- }
-
- public static void main(String[] args) {
- fun(new Bird("小鸟",15));
- fun(new Dog("二哈",8));
- fly(new Bird("小鸟",15));
- }
- }
接口完美解决了不能多继承的问题:

1.成员变量
抽象类当中可以有普通的成员变量,可以有静态的成员变量
接口的成员变量只能被public static final修饰
2.成员方法
抽象类可以构造方法,也可以有普通方法,不能被default修饰,可以有静态方法
但接口只能有抽象方法,或者被default修饰,或者静态方法
共同点是都不能实例化
区别是一个类只能继承一个抽象类,但是可以实现多个接口
对象之间不能直接比较大小
![]()
- package 接口;
- class Student implements Comparable
{ - String name;
- int age;
- double score;
-
- 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 +
- '}';
- }
-
- @Override
- public int compareTo(Student o) {
- if(o.score>this.score){
- return 1;
- }else if(o.score<this.score){
- return -1;
- }else{
- return 0;
- }
- }
- }
- public class Test3 {
- public static void main(String[] args) {
- Student student1=new Student("张三",18,98.5);
- Student student2=new Student("张三",18,97.5);
- if(student1.compareTo(student2)<0){
- System.out.println("student1>student2");
- }
- }
- }
注意比较方法:

如果直接排序会这样:
- Student student1=new Student("张三",18,98.5);
- Student student2=new Student("张三",15,97.5);
- Student student3=new Student("张三",12,97.5);
- Student student[]=new Student[]{student1,student2,student3};
- Arrays.sort(student);

sort方法比较对象时其实实现了Comparable接口,但是我们并没有实现compareto方法,所以我们要给比较的对象实现comparable接口并重写compareto方法
上述比较方式有一个缺陷,就是由于是在类里面写的比较方法,相当于比较方式唯一的,如果根据年龄比,就得重新修改,破坏了原来的比较方式
更加灵活:
根据用户需求自定义一个比较器(类)而不是直接在原来类里面写死比较方法
实现compartor接口,重写compare方法
- class AgeComparator implements Comparator
{ - @Override
- public int compare(Student o1, Student o2) {
- return o1.age - o2.age;
- }
- }
-
- class ScoreComparator implements Comparator
{ - @Override
- public int compare(Student o1, Student o2) {
- return (int) (o1.score - o2.score);
- }
- }
-
- public class Test3 {
- public static void main(String[] args) {
- Student student1 = new Student("张三", 18, 98.5);
- Student student2 = new Student("张三", 15, 97.5);
- Student student3 = new Student("张三", 12, 95.5);
- AgeComparator ageComparator = new AgeComparator();
- int ret = ageComparator.compare(student1, student2);
- System.out.println("年龄比较" + ret);
-
- ScoreComparator scoreComparator = new ScoreComparator();
- int ret2 = scoreComparator.compare(student1, student2);
- System.out.println("分数比较" + ret2);
- }
- Student student1 = new Student("张三", 18, 98.5);
- Student student2 = new Student("张三", 15, 97.5);
- Student student3 = new Student("张三", 12, 97.5);
- Student student[] = new Student[]{student1, student2, student3};
- AgeComparator ageComparator = new AgeComparator();
- Arrays.sort(student, ageComparator);
array.sort()可以传俩个参数,比较器和对象
- //自己实现sort比较对象
- public static void sort(Comparable[]array){
- for (int i = 0; i
1 ; i++) { - for (int j = 0; j
1-i ; j++) { - if(array[j].compareTo(array[j+1])>0){
- //不符合要求
- Comparable tmp=array[j+1];
- array[j+1]=array[j];
- array[j]=tmp;
- }
- }
- }
如果以后是自定义类型的数据,牵扯到大小比较,需要进行一些设计,比如实现接口
比较数组array.sort()构成了重载,可以传比较器,对象和只穿对象
string类型默认实现comparator接口,重写了compareTo方法,直接调用即可
克隆就是产生对象一个个副本
![]()
1.实现克隆接口:
其实这个接口cloneable当中,没有抽象方法,空接口/标记接口:当前类可以被克隆
2.重写克隆方法(重写的是object类克隆方法),底层是c++实现的不关注
- class Person implements Cloneable{
- public int age=10;
-
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
此时person已经具有了clone方法(object类的)
测试克隆:
需要向下转型
- public static void main(String[] args) throws CloneNotSupportedException {
- Person person=new Person();
- Person person2=(Person) person.clone();
-
- }
相当于新分配了内存,产生了新对象产生对象的副本,改变person2不会影响person1

我们给person类加一个money属性,money里存了m
- class Money{
- public int m;
- }
- class Person implements Cloneable{
- public int age=10;
- Money money=new Money();
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
- @Override
- public String toString() {
- return "Person{" +
- "age=" + age +
- '}';
- }
- }
通过测试修改第二个Person的m,第一个也随之改变
- public static void main(String[] args) throws CloneNotSupportedException {
- Person person=new Person();
- Person person2=(Person) person.clone();
- person.money.m=99;
- person2.money.m=180;
- System.out.println(person.money.m);
- }
此时输出180,第一个人存的钱变了???为什么这样呢
发生了浅拷贝:相互影响

不相互影响
效果如下:

1.给money实现克隆接口
- class Money implements Cloneable{
- public int m;
-
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
- }
2.修改Person的克隆使其能再拷贝出一个money,并返回tmp

- class Person implements Cloneable {
- public int age = 10;
- public Money m = new Money();
- @Override
- protected Object clone() throws CloneNotSupportedException {
- Person tmp = (Person) super.clone();
- tmp.m = (Money) this.m.clone();
- return tmp;
- // return super.clone();
- }
3.person调用clone方法返回值tmp(也就是新的money)给person2
Person person2 = (Person) person.clone();
这样修改
person2.m.money = 180;
不会影响person1.m.money了

深拷贝和浅拷贝不是那方法来决定
是取决于你代码的实现