抽象类和接口注意事项

注意1:抽象类的概念

**抽象类:**含有抽象方法的类称为抽象类。

**抽象方法:**父类 Shape 中的 show 方法好像并没有什么实际工作, 主要的绘制图形都是由 Shape
的各种子类的 show 方法来完成的. 像这种没有实际工作的方法, 我们可以把它设计成一个 抽象方法.

​ 抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。

注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法。

abstract public class Shape {
    public Shape(String name)
    {
        System.out.println("Shape构造方法");
        show();
    }
    abstract public void show();
    //抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。
}

注意2:抽象类的特性

1:抽象类不可以被实例化

Shape shape=new Shape();//error
abstract public class Shape {
        private String name;

        public Shape(String name)
        {
            System.out.println("Shape构造方法");
            this.name=name;
            //show();
        }

        abstract public void show();

        public String getName()
        {
            return this.name;
        }

}


abstract  class Cycle extends Shape {
    public Cycle  (String name,String sex)
    {
        super(name);
    }

}


public class A extends Cycle {
    public A(String name,String sex)
    {
        super(name,sex);
    }

    @Override
    public void show() {
        System.out.println(getName() +"hhh");
    }
}


public class Test {
    public static void main(String[] args) {

        Shape shape=new A("小白","男");
        shape.show() ;
        
        Shape shapes=new Cycle("小宝","女");//error  Cycle是抽象类不可以被实例化
    }

}

2:抽象类内的成员和普通类没有什么区别。

3:抽象类主要是被用来继承的。所以抽象方法一定不可以被private static final修饰。

4:如果一个类继承了这个抽象类,那么这个类必须重写抽象类当中的抽象方法。

abstract public class Shape {
        public Shape(String name)
        {
            System.out.println("Shape构造方法");
        }
    
        abstract public void show();//抽象方法

}


public class Cycle extends Shape {
    public Cycle  (String name)
    {
        super(name);
    }
    @Override//重写的注解  是父类某个方法的重写方法
    public void show() {
        System.out.println("画一个⚪");
    }
}

5:当抽象类A继承抽象类B,那么抽象类A可以不重写B中的方法,但是一旦A要是再被继承,那么一定还要重写

​ 这个抽象方法。

abstract public class Shape {
        private String name;

        public Shape(String name)
        {
            System.out.println("Shape构造方法");
            this.name=name;
            //show();           注意 :这里的show方法会调用所对应的子类的重写的show方法
        }

        abstract public void show();

        public String getName()
        {
            return this.name;
        }

}


abstract  class Cycle extends Shape {
    public Cycle  (String name,String sex)
    {
        super(name);
    }

}


public class A extends Cycle {
    public A(String name,String sex)
    {
        super(name,sex);
    }

    @Override
    public void show() {
        System.out.println(getName() +"hhh");
    }
}


public class Test {
    public static void main(String[] args) {

        Shape shape=new A("小白","男");
        shape.show() ;
    }

}

/*
输出结果:
Shape构造方法
小白hhh

*/


/*
如果把父类当中的show()方法打开的话
输出结果是:
Shape构造方法
小白hhh
小白hhh
*/

注意 :这里的父类中的构造方法中的show方法会调用所对应的子类的重写的show方法

在这里插入图片描述

注意3:接口的介绍

1:接口当中的方法都是抽象方法

2:其实也是有可以具体实现的方法。这个方法是被default实现的。//一般不这么使用

interface Shape 
{
    String name="ttt"; // public static final  修饰的常量。必须要赋值
    void show();       // public abstract 修饰的方法
    default String getName()
    {
        return this.name;
    }
}

3: 接口当中定义的成员变量默认是 public static final修饰的常量

成员方法是 public abstract 修饰的方法。其他修饰符都会报错。

​ 所以方法和属性可以不写修饰符

4:接口是不可以被实例化的。 联系:抽象类也是不可以被实例化的。

Shape shape=new Shape();//error

5:接口是interface

类与接口之间的关系是 implements

Cycle 使用 implements 来继承接口,此时表达的含义不是 “扩展” 而是 “实现”。

interface Shape 
{
    String name="ttt";  //public static final 常量
    void show();        //public abstract 方法
    default String getName()
    {
        return this.name;
    }
}


abstract  class Cycle implements  Shape
{
    
}


public class A extends Cycle 
{
    @Override
    public void show() 
    {
        System.out.println(getName() +"hhh");
    }
}


public class Test {
    public static void main(String[] args) 
    {
        Shape shape1=new A() ;
        shape1.show() ;
    }

}
/*
结果:
ttthhh
*/

6:接口是为了解决Java中的单继承问题,可以实现多个接口。(后面详细讲解)

7:如果一个类继承了这个接口,那么这个类必须重写抽象类当中的抽象方法。

8:只要这个类实现了这个接口,你就可以向上转型。

interface Shape 
{
    String name="ttt";  //public static final 常量
    void show();        //public abstract 方法
    default String getName()
    {
        return this.name;
    }
}


abstract  class Cycle implements  Shape
{
    
}


public class A extends Cycle 
{
    @Override
    public void show() 
    {
        System.out.println(getName() +"hhh");
    }
}


public class Test {
    public static void showShape(Shape shape)
    {
        shape.show();
    }
    public static void main(String[] args) {
        
        Shape shape1=new A();
        showShape (shape1 );

    }

}

/*
结果:
ttthhh
*/

9:接口中不能有静态代码块和构造方法

10:如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类

注意4:实现多个接口

Java中不支持多继承,但是一个类可以实现多个接口。

public interface IRunimg {

    void run();
    void fastrun();

}


public interface ISwimming {

    void swim();

}


public interface IFlying {

    void fly();

}


public class Animal {
    protected String name;

    public Animal(String name)
    {
        this.name=name;
    }

    public void eat()
    {

    }
}


public class Cat extends Animal implements IRunimg  {

    public Cat(String name)
    {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.name+"is running");
    }

    @Override
    public void fastrun() {
        System.out.println(this.name+"run fast");
    }
}


public class Frog extends Animal implements IRunimg ,ISwimming  {

    public Frog(String name)
    {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.name+"is running");
    }

    @Override
    public void fastrun() {
        System.out.println(this.name+"run fast");
    }

    @Override
    public void swim() {
        System.out.println(this.name+"is swimming");
    }
}


public class Test {

    public static void swim(ISwimming swimer)
    {
        swimer .swim() ;
    }

    public static void run(IRunimg  runner)
    {
        runner .run() ;
        runner.fastrun() ;
    }

    public static void fly(IFlying  flyer)
    {
        flyer.fly() ;
    }

    public static void main(String[] args) {

        Frog frog =new Frog("青蛙王子");
        Cat cat =new Cat("小白");

        run(cat);
        swim(frog);

    }
}


/*
小白is running
小白run fast
青蛙王子is swimming
*/

一个类继承一个父类, 同时实现多种接口 . 继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性 .

有了接口之后, 类的使用者就不必关注具体类型 , 而只关注某个类是否具备某种能力.

 public static void swim(ISwimming swimer)
 {
        swimer .swim() ;
 }

在这个 swim 方法内部, 我们并不关注到底是哪种动物, 只要参数是会游的就行。

使用接口的目的是:

例如:青蛙与猫都是动物,但是如果仅有继承的话,动物这个父类中有swim run fly 方法,那么子类青蛙中

就会有fly方法,猫中有swim和fly方法,但事实上,青蛙不会飞,猫不会游,所以这是就借用接口来实现。

都有的方法,就存在父类中,特有的方法就存在接口中。

注意5:接口使用实例

//错误写法:
public class Student
{
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


import java.util.Arrays;

public class Test
{
    public static void main(String[] args) {
        Student [] students=new Student[]
                {
                        new Student("塔图姆", 24),
                        new Student("库里", 34)
                };
        Arrays.sort(students);//不知道按照什么规范来排序
        System.out.println(Arrays.toString(students));
    }

}//error

在这里插入图片描述

在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.
然后比较当前对象和参数对象的大小关系(按分数来算).
如果当前对象应排在参数对象之前, 返回小于 0 的数字;
如果当前对象应排在参数对象之后, 返回大于 0 的数字;
如果当前对象和参数对象不分先后, 返回 0;
再次执行程序, 结果就符合预期了.

注意事项: 对于 sort 方法来说, 需要传入的数组的每个对象都是 “可比较” 的, 需要具备 compareTo 这样的能力. 通
过重写 compareTo 方法的方式, 就可以定义比较规则.

//正确写法:
public class Student implements Comparable<Student >//尖括号内是你要比较的类型
{
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Student o) {
        if(this.age>o.age)
        {
            return 1;

        }else if(this.age ==o.age)
        {
            return 0;

        }else
        {

            return -1;
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


public class Test
{
    public static void main(String[] args) {
        
        Student [] students=new Student[]
                {
                        new Student("塔图姆", 24),
                        new Student("库里", 34)
                };

        if( students[0].compareTo(students[1])<0 )    //student[0]调用compareTo()方法
        {
            System.out.println("stu[0]< stu[1]");
        }
        else if(students[0].compareTo(students[1])>0)
        {
            System.out.println("stu[0]> stu[1]");
        }
        else
        {
            System.out.println("stu[0]== stu[1]");
        }
    }

}
//结果:stu[0]< stu[1]
public class Student implements Comparable<Student >
{
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Student o) {
        if(this.age>o.age)
        {
            return 1;

        }else if(this.age ==o.age)
        {
            return 0;

        }else
        {

            return -1;
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


import java.util.Arrays;

public class Test
{
    public static void main(String[] args) {
        Student [] students=new Student[]
                {
                        new Student("杰森 塔图姆", 24),
                        new Student("斯蒂芬 库里", 34),
                        new Student("杰伦 布朗",26)
                };
        Arrays.sort(students);
        //在 sort 方法中会自动调用 compareTo 方法,有 Comparable 接口之后就知道比较啥了。
        System.out.println(Arrays.toString(students ) );
        //把数组名传进去,把数组里面的内容打印出来


    }

}
/*
[Student{name='杰森 塔图姆', age=24},
Student{name='杰伦 布朗', age=26},
Student{name='斯蒂芬 库里', age=34}]
*/

比较自定义类型时,使用comparable接口。

//根据名字的长度从大到小排序

public class Student implements Comparable<Student >
{
    private String name;
    private int age;
    private int score;

    public Student(String name, int age ,int score) {
        this.name = name;
        this.age = age;
        this.score =score;
    }

    @Override
    public int compareTo(Student o) {
        if(this.name.length() < o.name.length() ) // 小于的时候,我们返回1
        {
            return 1;

        }else if(this.name.length() ==o.name.length())
        {
            return 0;

        }else
        {

            return -1;
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}


import java.util.Arrays;

public class Test
{
    public static void main(String[] args) {
        Student [] students=new Student[]
                {
                        new Student("杰森 塔图姆", 24,13),
                        new Student("斯蒂芬 库里", 34,34),
                        new Student("杰伦 布朗",26,34)
                };
        Arrays.sort(students);
        System.out.println(Arrays.toString(students ) );

    }

}
/*
[Student{name='杰森 塔图姆', age=24 ,score=13},
Student{name='斯蒂芬 库里', age=34 ,score=34}, 
Student{name='杰伦 布朗', age=26 ,score=36}]
*/

//按成绩由高到低排序
package com.bit.demo3;

public class Student implements Comparable<Student >
{
    private String name;
    private int age;
    private int score;

    public Student(String name, int age ,int score) {
        this.name = name;
        this.age = age;
        this.score =score;
    }

    @Override
    public int compareTo(Student o) {
        if(this.score < o.score )
        {
            return 1;

        }else if(this.score ==o.score)
        {
            return 0;

        }else
        {

            return -1;
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}


package com.bit.demo3;

import java.util.Arrays;

public class Test
{
    public static void main(String[] args) {
        Student [] students=new Student[]
                {
                        new Student("杰森 塔图姆", 24,13),
                        new Student("斯蒂芬 库里", 34,34),
                        new Student("杰伦 布朗",26,36)
                };
        Arrays.sort(students);
        System.out.println(Arrays.toString(students ) );


    }

}
/*
[Student{name='杰伦 布朗', age=26, score=36},
Student{name='斯蒂芬 库里', age=34, score=34},
Student{name='杰森 塔图姆', age=24, score=13}]

*/
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chen森柏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值