小比特笔记--java抽象类、接口、Object类

本文介绍了Java编程中的抽象类、接口和Object类。讲解了方法重写的规则,强调了接口的使用优先级高于抽象类。通过USB接口的例子说明接口的多实现特性,并探讨了接口在实现多态中的作用。此外,还讨论了Object类的特性以及克隆和比较接口的使用场景。
摘要由CSDN通过智能技术生成

目录

复习重写

方法重写的类型的返回值必须严格相同:

抽象类

接口

代码:鼠标和键盘插入

兔子狗鸭子

关于接口的命名规范

Object类



复习重写

package abstract_class;

 class Person { //父类 parent class
    public void fun(){
        this.test();
    }
    private void test(){
        // The test method  is  private,Subclasses don't even know test exists.
        //so ,unable to rewrite.
        //private method only visible inside the current class.
        System.out.println("Person test method");
    }
}

class Student extends Person{//子类 subclasses
    public void test(){
        System.out.println("test method of student class ");
    }
}
public class Test{
    public static void main(String[] args) {
        new Student().fun();
        //The fun method only exists in parent class.
    }
}
package abstract_class;

 class Person { //父类 parent class
    public void fun(){
        this.test();
    }
     void test(){// After the elimination of private.
        System.out.println("Person test method");
    }
}

class Student extends Person{//子类 subclasses
     //The subclass is overridden 此时子类被重写了
    public void test(){
        System.out.println("test method of student class ");
    }
}
public class Test{
    public static void main(String[] args) {
        new Student().fun();
        //The fun method only exists in parent class.
    }
}

code output  "test method of student class "!!

子类和父类有不同的标记符号:

子类向上,父类向下;

方法重写的类型的返回值必须严格相同:

毫无相关的 两种类型不能作为方法重写的返回值,比如受父类中的是int而子类中的是boolean,这就不可以返回,不算方法重写,会报成不兼容。

这时子类使用student作为返回值,父类使用Person作为返回值是可以的,因为这个student本来就是Person, student is a person。

package abstract_class;

 class Person { //父类 parent class
    public void fun(){
        this.test();
    }
     Person test(){
        System.out.println("Person test method");
        return new Person();
    }
}

class Student extends Person{//子类 subclasses
    public  Student test(){
        System.out.println("test method of student class ");
        return  new Student();
    }
}
public class Test{
    public static void main(String[] args) {
        new Student().fun();
        //The fun method only exists in parent class.
    }
}

如果反过来父类中是返回Student,子类中返回person 呢?

会报错:“attempting to use incompatible return type”           尝试使用不兼容的类型。

原因这时是向下转型,而不是向上转型,person is not a  student,

package abstract_class;

 class Person { //父类 parent class
    public void fun(){
        this.test();
    }
     Student test(){
        System.out.println("Person test method");
        return new Student();
    }
}

class Student extends Person{//子类 subclasses
    public  Person test(){
        System.out.println("test method of student class ");
        return  new Person();
    }
}
public class Test{
    public static void main(String[] args) {
        new Student().fun();
        //The fun method only exists in parent class.
    }
}

一般情况下,重写方法的返回值类型不一定和父类相同,但是建议写成相同。

抽象类

抽象类只是比普通类多了一些抽象的方法,可以是0个或者n个。

抽象方法所在的类必须是抽象类,子类若继承了抽象类,必须重写所有的抽象方法(但是子类必须是普通类)。

抽象方法是使用abstract关键字声明,没有函数实现的方法。

java中定义抽象类或者抽象方法使用abstract关键字;

抽象方法的实现要在子类中去实现。

1只要使用抽象类必须用abstract声明为抽象类

此时的print只有方法的声明,没有方法体。所谓的方法体就是{}

没有方法体的方法不一定就是抽象方法。

本地方法native表示本地的,这个方法不是抽象方法,具体实现由C++写好的方法完成。

2若一个类使用abstract声明为抽象类,无法直接通过该类实例化对象,哪怕该类中一个抽象方法都没有。当一个类是抽象类,不管有没有抽象方法,这个类本身就是一个抽象的概念,没法具体到某个特定实例。

抽象类不能自己实例化对象,只能通过子类向上转型转为抽象父类的引用。

Sharp sharp =new Sharp();  // false

人类是一个抽象的概念

Person person= new Person(); // false

Person  person=new China(); //   true

        

3子类继承了抽象类就必须强制要求重写所有的抽象方法(子类是个普通类),一个子类只能extends一个抽象类

类“C”必须声明为抽象,或者实现抽象方法“printB()”

如果B中没有重写A,那么普通类C要实现两次
package Sharp;

public class code1 {
    abstract class A{
        abstract void printA();
    }
    //B 是一个抽象类,可以选择性的重写父类中的抽象方法
    abstract class B extends A{
        //这个pintA  B没有重写
        abstract void printB();
    }
    //C是普通类,必须重写B中的所有抽象方法
    class C extends B{
        @Override
        void printA() {
        }
        @Override
        void printB() {
        }
    }
}

如果B重写了A
package Sharp;

public class code1 {
    abstract class A{
        abstract void printA();
    }
    //B 是一个抽象类,可以选择性的重写父类中的抽象方法
    abstract class B extends A{
        abstract void printB();
        //如果我在B中重写了A,C就不需要重写两次了
        @Override
        void printA() {
        }
    }
    //C是普通类,必须重写B中的所有抽象方法
    class C extends B{

        @Override
        void printB() {
        }
    }}

4.抽象类虽然没法直接实例化对象,但是可以存在构造方法,子类在实例化对象的时候仍遵从继承的原则。先调用父类的构造方法,而后调用子类的构造方法。
package Sharp;

abstract class BaseTest{
    public BaseTest(){
        this.print();
    }
abstract void print();
}
public class Fun extends  BaseTest{
    private  int num=10;

    @Override
    void print() {
        System.out.println("num="+num);
    }

    public static void main(String[] args) {
        new  Fun();
    }
}

先调用父类,然后this.print()调用被子类重写的方法,此时num==0;

 到底啥时候会用到抽象类,稍微复杂一点,先阶段主要掌握接口类的定义与使用。

若一个需求既可以使用抽象类也可以使用接口,优先使用接口 ,因为抽象类依然是单继承局限。

接口

抽象类虽然没法直接实例化对象,但是子类仍然满足  is  a  原则,子类和抽象父类之间仍然是一个强的继承树关系,Person 对于China 和Sharp 对于Cycle, China 只能继承Person,  Cycle 只能继承 Sharp,而接口是一个混合的概念,他不是一个垂直的方向。接口的使用一般表示两种,

1.接口表示具备某种能力或者行为,子类在实现接口时不是 is  a 关系,而是具备这种行为能力。

比如 游泳 ,Person  满足游泳接口,  Dog也能满足游泳的接口,他是一个混合的实现,Duck 也能满足游泳接口,此时游泳接口就是一个表示游泳能力或者行为。

2.接口表示一种规范,比如“USB”接口,“5G标准”。

接口中只有全局常量和抽象方法,更加存粹的抽象概念,其他东西都没有。

接口使用关键字-interface声明接口,子类使用implement实现接口;

1.USB接口

 

 USB接口表示一种规范,那么显示生活中哪些类使我们接口的子类,鼠标,键盘这种外设都是。

子类使用implements实现接口,必须重写所有的抽象方法。

 

 电脑这个类不属于USB接口的子类,所有带USB线插入到电脑的设备都应该满足USB规范,电脑叫做USB规范的使用者。

 其实鼠标和键盘我们都需要各有一个接口,所以这个例子不太好。

代码:鼠标和键盘插入

package usb;

/**
 * 接口使用interface关键字定义,只有全局常量(1%会用),和抽象方法(99%是方法)
 */
public interface USB {
    // 插入
    public abstract  void plugIn();
    //工作
    public abstract void work();
}
package usb;

public class Mouse implements USB{

    @Override
    public void plugIn() {
        System.out.println("安装鼠标驱动");
    }

    @Override
    public void work() {
        System.out.println("鼠标开始工作");
    }
}
package usb;

public class KeyBoard implements USB{

    @Override
    public void plugIn() {
        System.out.println("安装键盘驱动中");
    }

    @Override
    public void work() {
        System.out.println("键盘正常工作");
    }
}
package usb;

public class Computer {
    public static void main(String[] args) {
        Computer computer=new Computer();
        Mouse mouse =new Mouse();
        //调用fun方法把mouse传入,插入一个鼠标
        computer.fun(mouse);
        KeyBoard keyBoard=new KeyBoard();
        computer.fun(keyBoard);
    }
       public void fun(USB usb){
        usb.plugIn();
        usb.work();
    }
}

安装鼠标驱动
鼠标开始工作
安装键盘驱动中
键盘正常工作

假如现在这可接口要插入Camera,电脑的fun方法不用变,只要写一个子类,然后创建对象,引用传入就行了,这也是多态。

开闭原则,所有设计模式的核心思想:程序应该的拓展开放,对修改关闭。方便扩展,不能影响已经写好的程序。

 

  

接口表现能力!

接口允许多实现,一个类可以具备多种能力        ,同时实现多父接口,若实现多个父接口,子类普通类,需要复写所有抽象方法。 

一个类既需要继承一个父类又需要实现多个接口时:

类名 extends 父类 implements 接口1,接口2...{}

兔子狗鸭子

package animal;

public interface ISWim {
    public abstract void swim();
}

package animal;

/**
 * 具备跑的能力或者行为
 */
public interface IRun {
    public abstract void run();
}

package animal;

/**
 * 表示具备飞的能力或行为
 */
public interface IFly {
    public abstract void fly();
}

package animal;
//兔子只会跑不会游泳
public class Rabbit implements IRun{
    @Override
    public void run() {
        System.out.println("兔子再跑~~");
    }
}

package animal;
//Dog会跑也会游泳
public class Dog implements IRun,ISWim{
    @Override
    public void run() {
        System.out.println("狗在跑~~~~");
    }

    @Override
    public void swim() {
        System.out.println("狗在游泳~~~~");
    }
}

package animal;
//鸭子会跑回游会飞
public class Duck implements IRun,IFly,ISWim {
    @Override
    public void fly() {
        System.out.println("鸭子在飞");
    }

    @Override
    public void run() {
        System.out.println("鸭子在跑");
    }

    @Override
    public void swim() {
        System.out.println("鸭子在游泳");
    }
}

package animal;

public class Test {
    public static void main(String[] args) {
        //接口也不能直接实例化对象,需要向上转型

        IRun run = new Rabbit();
        IRun run1 = new Dog();
        IRun run2 = new Duck();
        ISWim swim = new Dog();
        ISWim swim1 = new Duck();
        IFly fly = new Duck();
        run.run();
        run1.run();
        run2.run();
        swim.swim();
        swim1.swim();
        fly.fly();
    }
}

兔子再跑~~
狗在跑~~~~
鸭子在跑
狗在游泳~~~~
鸭子在游泳
鸭子在飞

由于接口中只会有全局常量和抽象方法,因此接口中

public abstract=>抽象方法

static final=>常量

全都可以省略!!!

package animal;

public class Test {
    public static void main(String[] args) {
        //接口也不能直接实例化对象,需要向上转型

        IRun run = new Rabbit();
        IRun run1 = new Dog();
        IRun run2 = new Duck();
        ISWim swim = new Dog();
        ISWim swim1 = new Duck();
        IFly fly = new Duck();
        run.run();
        run1.run();
        run2.run();
        swim.swim();
        swim1.swim();
        fly.fly();
    }
}

兔子再跑~~
狗在跑~~~~
鸭子在跑
狗在游泳~~~~
鸭子在游泳
全局常量
鸭子在飞
 

在定义抽象方法时,abstract和final不能同时出现,抽象方法必须 重写,final修饰后无法重写。

在定义抽象类时,也不可以,抽象类必须有子类,final修饰没有子类。

关于接口的命名规范

命名接口使用         I  开头,IRun,ISwim
子类实现一个接口时

命名以相应的接口开头,以impl结尾,

eg:如果是IRun的子类,以IRunimpl结尾,这个命名不是强制要求。

如果子类实现多个父接口不需要使用此规范来命名比如Duck即会游泳有会跑又会飞就不需要使用固定的结尾

Object类

全名称: 包名.类名

java.lang.Object

1.Object类是java中所有类默认的父类,无需使用extends来定义,class声明的类都有一个父类,Object类。

因为object类是所有类的父类,使用Object引用来接收所有类型,参数最高统一化。

Object obj1=new Person();

Object obj2=new String();

Object obj3=new Dog();

都可以通过向上转型变成object,所有类型都可以,这叫参数的最高统一化。

假如说有一个参数实object类型的,void fun(Object obj){},说明他可以接受所有的类型。

2.Object是所有类的父类,那么子类可以继承父类的所有方法!

之所以System.out.prientln(任意的引用类型)-->默认都调用toString()方法,是因为Object类存在toString方法。

这就是为什么sout中传入什么类型的对象都能够打印的原因。

还有,方法能不能重写看的是前面的引用有没有这个属性,如果有就调用子类重写后的代码:


3.java中引用数据类型之间的相等比较使用equals方法!        不能使用“==”比较的是地址;

Object类存在equals方法!

为啥不能用==比较引用?

package object_test;

/**
 * 为啥使用== 都是输出false?
 */

public class Object_Test {
    public static void main(String[] args) {
        Student student1=new Student("显平",80);
        Student student2=new Student("怡洲",81);
        Student student3=new Student("怡洲",81);
        //如果我现在要比较这stu1和stu2是否相等使用"=="
        System.out.println(student1==student2);
        System.out.println(student3==student2);

    }}
        class China { }
        class Dog {
    public String toString(){
            return "Dog类的toString方法。";}}

class Student{
    private String name;
    private int score;

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


false
false

因为“==”比较的是数值,对于引用数据类型来讲,保存的内容是一个地址,比较的其实就是地址。所以stud1,2,3的地址都不相等,都是false。

若需要比较两个对象的属性值是否相同就需要equals方法:

此时如果直接调用也是不对的:

JDK的源代码格式:

System.out.println(student2.equals(student3));

当前这个方法是谁通过哪个对象调用的,我的this就是谁。

equals方法是stud2,obj就是stu3。

这个代码比较的依然是stu2==stu3的地址,所以这个默认的比较方法不能满足我的需要,我就想知道学生的分数是不是相等。

下面我重写这个equals方法:来比较学生的分数属性

方法重写指的  除了权限不一样,返回值是boolean。方法的声明要一样。

权限子类大于等于父类,此时只能跟着public。方法名就叫equals,参数类型是Object obj,都要和父类完全一样。

this.score==student.score &&this.name.equals(student.name);

name属性是String类型,JDK中所有类型属性比较 都使用equals方法(能想到的头重写过了),==比较的是地址。

 

package object_test;

import com.oracle.webservices.internal.impl.internalspi.encoding.StreamDecoder;

/**
 * 为啥使用== 都是输出false?
 */

public class Object_Test {
    public static void main(String[] args) {
        Student student1=new Student("显平",80);
        Student student2=new Student("怡洲",81);
        Student student3=new Student("怡洲",81);
        Student student4=new Student("怡洲",80);
        //如果我现在要比较这stu1和stu2是否相等使用"=="
        System.out.println(student1==student2);
        System.out.println(student3==student2);
        System.out.println("----------");
        //这个方法其实比较的还是同一个学生的分两次的分数是不是一样。
        System.out.println(student2.equals(student3));
        System.out.println(student1.equals(student2));
        System.out.println(student1.equals(student4));

    }}
        class China { }
        class Dog {
    public String toString(){
            return "Dog类的toString方法。";}}

class Student{
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    @Override
    public boolean equals(Object obj){
        //若当前对象就是obj比如:自己等于自己
        // System.out.println(student2.equals(student2));
        if (this==obj){
            return true;
        }
        /**  走到这儿说明当前地址和obj确实不是一个地址,这个时候
         *  若此时obj指向的对象和student压根没有关系,没法比,直接返回false;
         *  那我咋判断student对象和object对象有没有关系呢?
         */
        if (obj instanceof Student){
            /**
             * 此时确实有关系了,其不是一个对象
             * Object obj=new Student();向下转型取出object
             */
            Student student=(Student)obj;
            return  this.score==student.score &&this.name.equals(student.name);
        }
        return  false;
    }
}
练习:自定义Student类,重写equals方法,比较自定义类型的属性值是否相等

Object不仅是所有class类的父类,而且JDK对Object做了扩展,Object可以接收所有引用数据类型的对象(接口,数组,类)

比如:Object obj1=new int[ 20 ] //接收了一个整形数组;

 若一个方法参数或者返回值是Object类型,说明该参数或者返回值是任意引用数据类型(数组,类,接口)
将八大基本类型包装成类,其他说有的引用都可以用Object来接收。
接口优先抽象类,因为接口灵活。

JDK内置常用接口:

java.lang.comparable:当一个类具备了comparable接口,表示这个类具备了可比较的能力。

package object_test;

public class Comparable_Test {
    public static void main(String[] args) {
        /**
         * 此时people这个数组中有几个对象,值是多少?
         */
        Person [] people=new Person[3];
        /**
         * people 是一个Person类型的数组,创建了三个Person类型的变量,值都是默认值null
         */
        System.out.println(people[0]);
        System.out.println(people[1]);
        System.out.println(people[2]);
    }

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

    String name;
    int age;

}

output:

null
null
null

创建的实例化

package object_test;

import java.util.Arrays;

public class Comparable_Test {
    public static void main(String[] args) {
        int [] data=new int[]{
        8,1,2};
        Arrays.sort(data);
        System.out.println(Arrays.toString(data));
    }
//        Person [] people=new Person[3];


}
当调用Arrays.sort给一个对象数组排序的时候,报转换类型异常
package object_test;

import java.util.Arrays;

public class Comparable_Test {
    public static void main(String[] args) {
        int [] data=new int[]{
        8,1,2};
        Arrays.sort(data);
        System.out.println(Arrays.toString(data));
        Person [] people=new Person[]{
                new Person("peter鹏哥",30),
                new Person("铭哥",18),
                new Person("显平",28)
        };
    // 根据年龄来排序:
        Arrays.sort(people);
        System.out.println(Arrays.toString(people));
    }

}

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

    String name;
    int age;

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

  为啥要把每个对象转成comparable?

对于data来说数值可以比较大小,但是Person这个类是自定义的,对于编译器来说不知道谁大谁小,像int这样的类型可以比较大小。

要让JDK知道谁大谁小,需要让Person类实现comparable接口,重写抽象方法compeTo,让Person这个类具备比较能力。

 

package object_test;

import java.util.Arrays;

public class Comparable_Test  {
    public static void main(String[] args) {
        int [] data=new int[]{
        8,1,2};
        Arrays.sort(data);
        System.out.println(Arrays.toString(data));
        Person [] people=new Person[]{
                new Person("peter鹏哥",30),
                new Person("铭哥",18),
                new Person("显平",28)
        };
    // 根据年龄来排序:
        Arrays.sort(people);
        System.out.println(Arrays.toString(people));
    }}
/**
 * 让Person implements Comparable 然后Override compareTo
 */
class Person implements Comparable{
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    String name;
    int age;
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public int compareTo(Object o) {
        //这里返回一个整形int
        if (this==o){
            return 0;
        }
        if (o instanceof Person){
            //当前传入对象O就是Person类型的引用,向下转型还原为Person;
            //要比较Person对象的大小关系,叫要用到Person 独有的属性,向下转型
            Person person=(Person) o;
            //此时就是根据年龄大小比较
            return this.age-person.age;
        }
        //报错,抛出异常
        throw new IllegalArgumentException("不是Person类型,无法比较。");
    }
}

 [1, 2, 8]
[Person{name='铭哥', age=18}, Person{name='显平', age=28}, Person{name='peter鹏哥', age=30}]

现在想用自己的sor方法t排序调用compareTo

package object_test;

import java.util.Arrays;

public class Comparable_Test  {
    public static void sort(Comparable[]arr){
        for (int i = 0; i < arr.length-1; i++) {
            for (int j = 0; j < arr.length-i-1; j++) {
//if (arr[j]>arr[j+1])//swap
                if (arr[j].compareTo(arr[j+1])>0){
//前一个大于后个,交换j和j+1
                    Comparable temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
    }
    public static void main(String[] args) {
 
        Person [] people=new Person[]{
                new Person("peter鹏哥",30),
                new Person("铭哥",18),
                new Person("显平",28)
        };
    // 根据年龄来排序:
        sort(people);
        System.out.println(Arrays.toString(people));
    }}
/**
 * 让Person implements Comparable 然后Override compareTo
 */
class Person implements Comparable{
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    String name;
    int age;
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public int compareTo(Object o) {
        //这里返回一个整形int
        if (this==o){
            return 0;
        }
        if (o instanceof Person){
            //当前传入对象O就是Person类型的引用,向下转型还原为Person;
            //要比较Person对象的大小关系,叫要用到Person 独有的属性,向下转型
            Person person=(Person) o;
            //此时就是根据年龄大小比较
            return this.age-person.age;
        }
        //报错,抛出异常
        throw new IllegalArgumentException("不是Person类型,无法比较。");
    }
}
如何变成降序输出compareTo?

改成这就行了

克隆接口,java.lang.Cloneable

 克隆羊“多力”

原对象和新对象确实是两个独立的对象,新产生的对象是通过原对象拷贝而来的,属性值和原对象完全一致。

要让一个类具备可复制的能力,实现cloenable接口,重写clone方法。

这种接口里面是Null ,称为标记接口。(标记接口指内部本身没有任何抽象方法,只有打上这个标记的子类才具备克隆的能力,克隆的能力从JVM中来){生活中的标记:猪场养猪,猪长成熟后会被检查身体指标,达到使用标准之后会打上合格的标签。

}JVM在运行时会检查所有实现了Cloneable接口的子类, 赋予其克隆的能力,clone是object方法。通过贴标签把不同的类划分。

 

package object_test;

public class CloneableTest {
    public static void main(String[] args) {
        Animal animal1=new Animal("test");
        //animal2是同过animal1克隆复制过来的,确实是两个独立的对象,属性值完全相同。
        Animal animal2=animal1.clone();
        //animal1 和animal2的地址不相等打印的false
        System.out.println(animal1==animal2);
        System.out.println(animal2.name);
    }
}
class Animal implements Cloneable{
    String name;
    public Animal(String name){
        this.name=name;
    }
    public Animal clone(){
        Animal newAnimal=null;
        try {
            newAnimal=(Animal) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return newAnimal;
    }

}

 为甚么我们叫anima1和animal2叫克隆,而animal3和animal1之间没有关系?

只是new animal3的时候恰好等于animal1而已。

比如世界上还要一个属性值和克隆羊多力相同的羊,但是这个羊和多力的基因羊母亲么有关系,而animal2的产生是一样animal1的。        

animal3的产生是天然的,和克隆无关。

 

深浅拷贝

快捷键 Alt +Enter

 深拷贝:每个对象自身包含的对象也是拷贝出来的。
浅拷贝:每个对象自身包含的对象指向的是同一个对象。

package object_test;

public class DeepCopyTest {
    public static void main(String[] args) {
        B b1=new B();
        B b2=b1.clone();
        System.out.println(b1==b2);
        System.out.println(b1.a== b2.a);
        b1.a.num=100;
        System.out.println(b2.a.num);
    }
}
class A{
    int num;
}
class B implements Cloneable{
    A a=new A();
    public  B clone(){
        B newB=null;
        try {
            newB=(B) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return newB;
    }
}

Deep Clone瞅一眼:了解就行了        

让A也实现深拷贝,

package object_test;

public class DeepCopyTest {
    public static void main(String[] args) {
        B b1=new B();
        B b2=b1.clone();
        System.out.println(b1==b2);
        System.out.println(b1.a== b2.a);
        b1.a.num=100;
        System.out.println(b2.a.num);
    }
}
class A implements  Cloneable{
    int num;
    public A clone(){
        A a=null;
        try {
            a=(A) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return a;
    }
}
class B implements Cloneable{
    A a=new A();
    public  B clone(){
        B newB=null;
        try {
            newB=(B) super.clone();
            newB.a=newB.a.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return newB;
    }
}
接口和类之间的关系
package object_test;

public class TTest {

}
interface IA{
    void testA();
}
interface IB{
    void testB();
}
//IC接口同时继承了多个父接口,继承了所有抽象方法,
//子类在实现IC接口的时候,必须重写所有的抽象方法
interface IC extends IA,IB{
    class CImpl implements IC{
        // CImpl如果继承IC需要继承两个方法
//具备了IC和IB的抽象方法
        @Override
        public void testA() {

        }

        @Override
        public void testB() {

        }
    }
}
既需要继承一个父类又需要实现多个接口
abstract China extends Person implements IB,IA{}

先extens然后implements

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值