【抽象类和接口】

news/2024/9/30 4:21:22/

目录

  • 1.抽象类
    • 1.1什么是抽象类
    • 1.2抽象类语法
    • 1.3抽象类与普通类的区别
  • 2.抽象类的特性
    • 2.1 特性
    • 2.2抽象类的作用
  • 3.接口
    • 3.1什么是接口
    • 3.2语法规范
    • 3.3接口的使用
    • 3.4接口的特性
    • 3.5 实现多个接口
    • 3.6 接口的继承
  • 4.接口的实例
  • 5.Clonable 接口和深拷贝
    • 5.1 浅拷贝
    • 5.2深拷贝
  • 6. 抽象类和接口的区别

1.抽象类

1.1什么是抽象类

在我们Java面对对象的概念中,所有的对象都是通过类来描述的,但是有一些对象不能通过类来描述。
如果一个类中没有足够的系信息去描绘一个具体的对象,这个类就是抽象类。
在这里插入图片描述

说明:
1.Animal是动物类,每个动物都有叫的方法,但由于Animal不是一个具体的动物,因此其内部eat()方法无法具体实现
2.Dog是狗类,首先狗是动物,因此与Animal是继承关系,其次狗是一种具体的动物,狗叫:汪汪汪,其eat()可以实现
3.Cat是猫类,首先猫是动物,因此与Animal是继承关系,其次猫是一种具体的动物,猫叫:崛瞄瞄,其eat()可以实现
4.因此:Animal可以设计为“抽象类"

我们可以看出来,父类的eat()方法,并不是一个实际的工作,主要的各种子类的eat()方法来实现的,像这种没有实际工作的方法,我们一般可以设为一个抽象方法。包含抽象方法的类称为抽象类。

1.2抽象类语法

如果一个类,被abstract修饰,那么这个类就是一个抽象类,这个类中,被abstract修饰的方法,称为抽象方法。

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

abstract class A
{abstract public void func();}
class B extends A
{@Overridepublic void func() {System.out.println("B的方法");}
}
public class Test {public static void main(String[] args) {A a=new B();a.func();}
}

1.3抽象类与普通类的区别

1.抽象类不能实例化,普通类可以实例化
在这里插入图片描述
2.抽象类中,可以包含抽象方法和普通方法,但是普通类只能包含非抽象方法。
在这里插入图片描述

2.抽象类的特性

2.1 特性

1.抽象类使用abstract修饰类
2.抽象类不能被实例化。
3.此时在抽象类当中,可以有抽象方法,或者非抽象方法!
4.什么是抽象方法,一个方法被abstract修饰,没有具体的实现。只要包含抽象方法,这个类必须是抽象类!
5.当一个普通类继承了这个抽象类,必须重写抽象类当中的抽象方法!
6.抽象类存在的最大的意义,就是为了被继承!
7.抽象方法不能被private , final , static修饰。所以一定要满足方法重写的规则!!
8.当一个子类没有重写抽象的父类的方法,可以把当前子类变为abstract修饰。
9.抽象类中,不一定包含抽象方法

2.2抽象类的作用

抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.

确实如此. 但是使用抽象类相当于多了一重编译器的校验.
使用抽象类的场景就如上面的代码, 实际工作不应该由父类完成, 而应由子类完成. 那么此时如果不小心误用成父类了, 使用普通类编译器是不会报错的. 但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题.

3.接口

3.1什么是接口

接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。
在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型

3.2语法规范

我们接口的定义跟类差不多,就是把class换位interface关键字,就可以定义了一个接口。

interface IShape{public int age=2;public String name="1";//默认是这个public static final String sex="1";//方法默认这个public abstract void draw();//也可以default public  void func(){System.out.println("66666666");}public static void staticfunc(){System.out.println("staticfunc");}
}

注意:

  1. 创建接口时, 接口的命名一般以大写字母 I 开头.
  2. 接口的命名一般使用 “形容词” 词性的单词.
  3. 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性.

3.3接口的使用

接口不能直接的使用,必须要有一个类来实现这个接口,实现接口中的抽象方法

子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。

public class 类名称 implements 接口名称{
// ...
}
public class Mouse implements USB{@Overridepublic void openDevice() {System.out.println("打开鼠标");}@Overridepublic void closeDevice() {System.out.println("关闭鼠标");}public  void click(){System.out.println("点击鼠标");}
}

3.4接口的特性

大家如果想用这个东西你必须实现一下我的规范。
1.使用关键字interface来定义接口
2.接口不能被实例化
3.接口当中的成员默认是public static final
4.接口当中的方法不写也是默认为public abstract的
5.接口当中的方法不能有具体的实现,但是从JDK8开始可以写一个default修饰的方法
6.接口当中不能有构造方法
7.接口需要被类实现,使用关键字implements
8.接口当中可以有static修饰的方法!
9. 重写接口中方法时,不能使用默认的访问权限
10.接口中不能有静态代码块和构造方法

3.5 实现多个接口

在Java中,类和类之间是单继承的,一个类只能有一个父类,即Java中不支持多继承,但是一个类可以实现多个接口。

下面通过类来表示一组动物.。
并且在定义几个接口表示跑,游泳,飞等等。
接下来我们创建几个具体的动物,具体实现这几个接口

注意:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。

abstract class Animal {public String name;public Animal(String name) {this.name = name;}
}
interface IRunning {void run();
}
interface ISwimming {void swim();
}interface IFly {void fly();
}class Dog extends Animal implements IRunning {public Dog(String name) {super(name);}@Overridepublic void run() {System.out.println(name +" 正在用四条狗腿跑!");}
}class Fish extends Animal implements ISwimming{public Fish(String name) {super(name);}@Overridepublic void swim() {System.out.println(name + "正在游泳!");}
}
class Bird extends Animal implements IFly {public Bird(String name) {super(name);}@Overridepublic void fly() {System.out.println(name + "正在飞!");}
}
class Duck extends Animal implements IRunning,IFly,ISwimming {public Duck(String name) {super(name);}@Overridepublic void run() {System.out.println(name + "正在用两条腿跑!");}@Overridepublic void swim() {System.out.println(name + "正在用两条腿在游泳!");}@Overridepublic void fly() {System.out.println(name + "正在用翅膀飞!");}
}class Robot implements IRunning{@Overridepublic void run() {System.out.println("机器人在用机器腿跑步!");}
}public class Test4 {/*** 只要实现了 IRunning 接口的 都可以接收* @param iRunning*/public static void walk(IRunning iRunning) {iRunning.run();}public static void swim(ISwimming iSwimming) {iSwimming.swim();}/*** 一定是一个动物* @param animal*/public static void func(Animal animal) {}public static void main(String[] args) {walk(new Dog("旺财"));walk(new Duck("唐老鸭"));walk(new Robot());System.out.println("======");swim(new Fish("七秒"));swim(new Duck("唐老鸭2号"));}
}

这样设计有什么好处呢? 时刻牢记多态的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型,而只关注某个类是否具备某种能力.

3.6 接口的继承

在Java中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到多继承的目的。

接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字.

interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}

4.接口的实例

当我们定义了一个Stydent类,里面定义了两个属性,一个姓名,一个年纪。
当我们 new 了三个对象的时候,我们想给他排序,这应该怎么办?当我们只用原本的sort()方法会发现报错。

Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable

那么我们应该怎么办?当我们的对象里面有两个属性,这个时候我们不会知道按照那个属性去排序,就会出现错误。
所以我们就要重写方法,让这个方法按照我们想排序的属性去进行比较。

package demo3;import java.util.Arrays;
import java.util.Comparator;class Student
{public String name;public int age;public int score;public Student(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}
}class Agecomparator implements Comparator<Student>
{@Overridepublic int compare(Student o1, Student o2) {return o1.age-o2.age;}
}class Scorecomparator implements Comparator<Student>
{@Overridepublic int compare(Student o1, Student o2) {return o1.score-o2.score;}
}class Namecomparator implements Comparator<Student>
{@Overridepublic int compare(Student o1, Student o2) {return o1.name.compareTo(o2.name);}
}
public class test {public static void main(String[] args) {Student[] students=new Student[3];students[0]=new Student("zhangsan",10,10);students[1]=new Student("lisi",20,20);students[2]=new Student("wangwu",30,30);Agecomparator getcomparator=new Agecomparator();Arrays.sort(students,getcomparator);System.out.println(Arrays.toString(students));System.out.println("===========");Scorecomparator scorecomparator=new Scorecomparator();Arrays.sort(students,scorecomparator);System.out.println(Arrays.toString(students));System.out.println("===============");Namecomparator namecomparator=new Namecomparator();Arrays.sort(students,namecomparator);System.out.println(Arrays.toString(students));}
}

0

5.Clonable 接口和深拷贝

Java 中内置了一些很有用的接口, Clonable 就是其中之一.

Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常

5.1 浅拷贝

class Money
{public double money=12.25;}
class Student implements Cloneable
{public String name;public Money m=new Money();@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class test {public static void main(String[] args) throws CloneNotSupportedException {Student student=new Student();student.name="123";Student student1=(Student) student.clone();System.out.println(student);System.out.println(student1);System.out.println("==========");student1.m.money=99;System.out.println(student.m.money);System.out.println(student1.m.money);}
}

在这里插入图片描述
如上代码,我们可以看到,通过clone,我们只是拷贝了Student对象。但是Student对象中的Money对象,并
没有拷贝。通过Student1这个引用修改了m的值后,Student1这个引用访问m的时候,值也发生了改变。这里
就是发生了浅拷贝。
在这里插入图片描述

5.2深拷贝

package demo4;class Money implements Cloneable
{public double money=12.25;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
class Student implements Cloneable
{public String name;public Money m=new Money();@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {Student student=(Student) super.clone();student.m=(Money)this.m.clone();return student;//return super.clone();}
}
public class test {public static void main(String[] args) throws CloneNotSupportedException{Student student=new Student();Student student1=(Student) student.clone();System.out.println(student.m.money);System.out.println(student1.m.money);System.out.println("=============");student1.m.money=99;System.out.println(student.m.money);System.out.println(student1.m.money);}public static void main1(String[] args) throws CloneNotSupportedException {Student student=new Student();student.name="123";Student student1=(Student) student.clone();System.out.println(student);System.out.println(student1);}
}

在这里插入图片描述
如上代码,我们可以看到,通过clone,我们只是拷贝了Student对象。并且Student对象中的Money对象也进行了拷贝。通过Student1这个引用修改了m的值后,Student个引用访问m的时候,值也发生了改变。这里
就是发生了深拷贝。
在这里插入图片描述

6. 抽象类和接口的区别

核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法,子类必须重写所有的抽象方法.

如之前写的 Animal 例子. 此处的 Animal 中包含一个 name 这样的属性, 这个属性在任何子类中都是存在的. 因此此处的 Animal 只能作为一个抽象类, 而不应该成为一个接口。

在这里插入图片描述


http://www.ppmy.cn/news/188655.html

相关文章

mt6765和骁龙665哪个好_mtkmt6765相当于骁龙多少

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 mtkmt6765相当于骁龙630。 骁龙630是美国高通公司设计的移动处理器。作为骁龙625的继承者&#xff0c;骁龙630处理器完全继承了前者的定位&#xff0c;主打主流性能的中端机型。骁龙…

骁龙778g相当于天玑多少 骁龙778g和天机1000+哪个好

骁龙778G&#xff1a;这款处理器采用的是6nm的制作工艺 天玑1000&#xff1a;采用了7nm工艺制程&#xff0c;目前最为熟练的旗舰芯片的制作方式 我用的手机就是活动时8折抢购的机会不容错过 http://www.adiannao.cn/7 骁龙778G&#xff1a;“134”八核架构&#xff0c;2.4GHz A…

骁龙730g处理器怎么样 骁龙730g相当于麒麟多少 骁龙730g是什么级别

骁龙730g属于中高端的处理器&#xff0c;骁龙730G处理器其CPU采用了Kryo 470 26大小核架构&#xff0c;2颗2.2Hz大核6颗1.7Hz小核的核心设计能够灵活应对各种负载场景。 骁龙730g处理器怎么样这些点很重要看过你就懂了 http://shouji.adiannao.cn/7 实现了高达35%的性能提升&am…

骁龙780G和骁龙768G参数对比 骁龙780G和骁龙768G差距大不大

骁龙780G采用了6nm的制作工艺&#xff0c;可以减少能耗;骁龙768G采用的台积电的7nm制作工艺&#xff0c;为用户带来更低的芯片功耗; 我用的手机就是活动时8折抢购的 点击开抢 http://shouji.adiannao.cn/7 骁龙780G采用的是“116”的架构&#xff0c;为用户提供了一个1Cortex A…

骁龙778gplus什么水平 骁龙778gplus什么级别 骁龙778gplus相当于什么档次

这款处理器性能高于骁龙778G&#xff0c;低于骁龙780G属于中端处理器。 高通骁龙778G Plus芯片&#xff08;采台积电6nm&#xff0c;4x2.4GHz A784x1.8GHz A55&#xff0c;比768G提升40%;还有Adreno 642L GPU&#xff0c;图形性能提升20%)。 骁龙778gplus怎么样这些点很重要 ht…

骁龙768G相当于什么处理器 骁龙780g什么水平

骁龙768G 是一款定位中端的芯片&#xff0c;是一款集成5G芯片&#xff0c;这款不同于骁龙765G&#xff0c;在GPU等等众多方面&#xff0c;都有不小的提升。性能分析&#xff1a;相比骁龙 765、765G处理器&#xff0c;此次推出的骁龙 768G 处理器相当于骁龙765G的升级版。我用的…

天玑1300和骁龙778plus哪个好

高通骁龙778G Plus芯片&#xff08;采台积电6nm&#xff0c;4x2.4GHz A784x1.8GHz A55&#xff0c;比768G提升40%;还有Adreno 642L GPU&#xff0c;图形性能提升20%)。 选天玑1300还是骁龙778plus这些点很重要 http://www.adiannao.cn/7 骁龙778G是高通首款6nm 5G处理器&#…

高通骁龙765/骁龙765G芯片参数分析介绍

昨天&#xff0c;高通亮相了全新的骁龙765和骁龙765G 5G SOC&#xff0c;今天高通正式公布了这两款处理器的详细规格&#xff0c;一起来看一下吧。 端到端5G连接&#xff1a; 骁龙765集成骁龙X52调制解调器及射频系统&#xff0c;峰值下载速率高达3.7 Gbps&#xff0c;上传速率…