java基础-接口、继承、多态

 

 

 女神镇楼

2、Object类

 是什么===Object类是比较特殊的类,是所有类的父类,是java类层中的最高层类。创建一个类时,它总是在继承,除非某个类指定他从某个类继承,否则他就是从java.lang.Object类继承来。

在Object类中主要包括clone()、finalize()、equals()、toString(等方法,其中常用的两个方法为equals()
和toString(方法。由于所有的类都是Object类的子类,所以任何类都可以重写Object类中的方法。

class Anything{
 	...
}	
//等价于
class Anything extends Object{
	...
}

Object类中的getClass()、notify()、 notifyAll()、 wait()等 方法不能被重写,因为这些方法被定义为final类型。

 

Object类中的几个重要方法:    

 (1)getClass()方法

        getClass()方法是Object类定义的方法,返回对象执行时的Class实例,然后用此实例调用getName()方法获取类的名称。

     getClass().getname();

 

(2)toString()方法

        toString方法功能是将一个对象返回字符串形式,返回一个String实例,在实际应用中,通常需要重写toString()方法,为对象提供一个特定的输出模式。当这个类转换为字符串或者字符串连接时,会自动重写toString()方法。

        代码示例:

public class ObjectInstance {
    public String toString(){
        return "在"+getClass().getName()+"类中重写了toString方法";
    }

    public static void main(String[] args) {
        System.out.println(new ObjectInstance());
    }
}

 

 

 (3)equal()方法 == 用来比较两个对象的实际内容,“==”是比较两个对象的引用是否相等

    代码示例:

class V{}
public class OverWhiteEqual {
    public static void main(String[] args) {
        String s1 = "123";
        String s2 = "123";
        System.out.println(s1.equals(s2));

        V v1 = new V();
        V v2 = new V();
        System.out.println(v1.equals(v2));
    }
}

 

 

实例分析:

    在自定义类中使用equals()方法进行比较时,返回false,因为equals()方法默认实现的是“==”比较两个对象的引用地址,而不是比较对象的内容,所以要想做到真正的比较两个对象的内容,需要在自定义类中重写equals()方法

 

3、对象的类型转换

(1)向上转型

    代码示例:定义平行四边形类和四边形类

public class Quadrangle { // 四边形类
    public static  void draw(Quadrangle q){ // 四边形类中的方法
        System.out.println("四边形类中输出!");
    }
}

 

public class Parallelogram extends Quadrangle {
    public static void main(String[] args) {
        Parallelogram p = new Parallelogram();
        draw(p);
    }
}

 

     实例分析:

        四边形类中有draw()方法,参数是Quadrangle(四边形类),在平行四边形类中调用的时候传的参数是Parallelogram(平行四边形类)。这里需要强调一下,平行四边形也是一种类型的四边形,所以平行四边形类的对象可以看做四边形类的对象,相当于“Quadrangle obj = new Parallelogram”,就是吧子类对象赋值给父类类型的变量,称之为向上转型。

平行四边形类继承了四边形类,常规的继承图都是将顶级类设置在页面的顶部,然后逐渐向下,所以将子类对象看作是父类对象被称为“向上转型”。

由于向上转型是从一个较具体的类到较抽象的类的转换,所以它总是安全的,如可以说平行四边形是特殊的四边形,但不能说
四边形是平行四边形。

 

(2)向下转型

        向下转型是将较抽象类转换为较具体的类,可以说子类对象总是父类的一个实例,但父类对象不一定是子类的实例。

        代码示例:

public class Quadrangle { // 四边形类
    public static  void draw(Quadrangle q){ // 四边形类中的方法
        System.out.println("四边形类中输出!");
    }
}
public class Parallelogram extends Quadrangle {
    public static void main(String[] args) {
        Parallelogram p = new Parallelogram();
        draw(p);
        //将平行四边形类对象看做四边形类对象,成为向上转型操作
        Quadrangle q = new Parallelogram();
        Parallelogram p1 = q;
        /* 将父类对象赋给子类对象,这种写法是错误的 */
        // 将父类对象赋予子类对象,并强制转换为子类型。这种写法是正确的
        Parallelogram p2 = (Parallelogram) q;
    }
}

   实例分析:

        父类对象直接赋予子类,会发生编译器错误,因为父类不一定是子类的实例,

越是具体的对象具有的特性越多,越是抽象的对象,具有的对象越少。

在向下转型操作中,将特性范围小的对象转型为特性范围大的对象会出现问题。

这时候父类对象强制转换为某个子类对象,称为显式类型转换。在程序中使用向下转型操作时,必须使用显式类型转换。

 

4、使用instanceof操作符判断对象类型

        向下转型操作时,先判断父类对象是否是子类的实例,instanceof 操作符,可以判断一个引用指向的对象是否是某一个类型或者其子类, 是则返回true,否则返回false。

instanceof的语法格式如下:
 

 myobject instanceof ExampleClass 


myobject: 某类的对象引用。
ExampleClass:某个类。
使用instanceof 操作符的表达式返回值为布尔值。如果返回值为true, 说明myobject 对象为
ExampleClass的实例对象;如果返回值为false,说明myobject对象不是ExampleClass的实例对象。

 

  代码示例:

public class Quadrangle {
    public static void draw(Quadrangle q){
        System.out.println("Quadrangle的draw方法");
    }
}
public class Square extends Quadrangle {
    // SomeSentence
}
public class Anything {
    //SomeSentence
}
public class Parallelogram extends Quadrangle {
    public static void main(String[] args) {
        Quadrangle q =new Quadrangle(); //实例化父类对象
        //判断父类对象是否是Parallelogram子类的一个实例 ,
        if(q instanceof Parallelogram){
            Parallelogram p = (Parallelogram) q; // 向下转型操作
        }
        // 判断父类对象是否是Square子类的一个实例
        if(q instanceof Square){
            Square s = (Square) q; //向下转型操作
        }
        // 由于q对象不是Anything类的对象,所以这条语句是错误的
        //System.out.println(q instanceof Anything);
    }
}
public class Parallelogram extends Quadrangle {
    public static void main(String[] args) {
        Quadrangle q =new Quadrangle(); //实例化父类对象
        //判断父类对象是否是Parallelogram子类的一个实例 ,
        if(q instanceof Parallelogram){
            Parallelogram p = (Parallelogram) q; // 向下转型操作
        }
        // 判断父类对象是否是Square子类的一个实例
        if(q instanceof Square){
            Square s = (Square) q; //向下转型操作
        }
        // 由于q对象不是Anything类的对象,所以这条语句是错误的
        //System.out.println(q instanceof Anything);
    }
}

 

5、方法的重载

        构造方法的名称是由类名决定的,所以构造方法只有一个名称,如果希望不同的方式来实例化对象,就需要使用多个构造方法完成,为了让方法名相同而形参不同的构造方法同时存在, 就需要用到方法重载。

        代码示例:

public class OverLoadTest {
    public static int add(int a, int b){
        return a+b;
    }
    public static double add(double a, double b){
        return a+b;
    }
    public static int add(int a){
        return a;
    }
    public static int add(int a, double b){
        return 1;
    }
    public static int add(double a, int b){
        return 1;
    }

    public static void main(String[] args) {
        System.out.println("调用add(int,int)方法:"+add(1,2));
        System.out.println("调用add(double,double)方法:"+add(2.1,3.3));
        System.out.println("调用add(int)方法:"+add(1));
    }
}

 

 

构成重载的条件,可以总结出编译器是利用方法名、方法各参数类型、参数的个数、参数的顺序来判断类中的方法是否唯一。

6、多态

       将父类对象应用于子类的特征就是多态,利用多态可以是程序具有良好的拓展性,并可以对所有类对象进行通用处理。

        实例:一个四边形类,让它处理所有继承该类的对象,根据“向上转型”的原则,可以使每个继承这个四边形类的对象作为draw()方法的参数,然后在draw()方法中做出一些限制,就可以根据不同的图形类对象绘制不同的图像,这样就可以使用更为通用的四边形类取代具体的正方形类和平行四边形类,可以很好的解决代码冗余的问题,并且更易于维护。

        代码示例:

public class Quadrangle {
    // 实例化保存四边形对象的数组对象
    private Quadrangle[] qtest = new Quadrangle[6];
    private int nextindex = 0;
    /*定义draw方法,参数是四边对象*/
    public void draw(Quadrangle q){
        if(nextindex < qtest.length){
            qtest[nextindex] = q;
            System.out.println("输出参数nextindex数值:"+nextindex);
            nextindex ++;
        }
    }

    public static void main(String[] args) {
        // 实例化两个四边形对象,用来调用draw方法
        Quadrangle q = new Quadrangle();
        q.draw(new Square()); // 以正方形对象为参数调用draw方法
        q.draw(new Parallelogram()); // 以平行四边形对象为参数调用draw方法
    }
}

 

//定义一个正方形类继承自四边形类
public class Square extends Quadrangle {
    // SomeSentence
    public Square(){
        System.out.println("正方形");
    }
}
// 定义一个平行四边形类继承自四边形类
public class Parallelogram extends Quadrangle {
    public Parallelogram(){
        System.out.println("平行四边形");
    }
}

实例分析:

        以不同的类对象为参数调用draw方法,可以处理不同的图形问题。

 

7、抽象类

    在实际解决问题时,一般将父类定义为抽象类,需要使用这个父类进行继承和多态处理。继承树中,越上方的类,越是抽象。在多态机制中,不需要将父类初始化对象,我们需要的只是子类对象。

 抽象类的语法如下:

public abstract class Test {
    abstract void testAbstract(); // 定义抽象方法
}

 

 其中,abstract是抽象类的关键字。

    使用abstract关键字定义的类称之为抽象类,使用这个关键字定义的方法称为抽象方法,抽象方法没有具体的方法体,这个方法本身是没有意义的,除非他被重写,而承载这个抽象方法的抽象类必须被继承,实际上抽象类除了被继承之外没有任何意义。

    只要类中有抽象方法,这个类必须被定义为抽象类。

    抽象类被继承后需要实现其中所有的抽象方法。

 

8、接口

    接口是抽象类的延伸,可以看作是纯粹的抽象类,接口中所有的方法都没有方法体。

    接口使用interface关键字进行定义,语法如下:

public interface drawTest2 {
    void draw(); // 接口中的方法省略abstract关键字
}

 

一个类实现一个接口可以使用implements关键字,语法如下:

public class Parallelogram extends Quadrangle implements drawTest2 {
    public Parallelogram(){
        System.out.println("平行四边形");
    }

    @Override
    public void draw() {
        
    }
}

  

  接口中定义的方法必须被定义为public或者abstract形式,其他的修饰权限不被java编辑器认可。

    实例代码:

//定义drawTest接口
public interface drawTest {
    void draw();
}
//定义四边形类
public class QuadrangleUseInterface {
    public  void doAnything(){

    }

    public static void main(String[] args) {
        drawTest[] d = {
                new SquareUseInterface(),
                new ParallelogramgleUseInterface()
        };
        for(int i = 0 ;i<d.length ; i++){
            d[i].draw();
        }
    }
}
//定义平行四边形类,继承了四边形类,并实现了drawTest接口
public class ParallelogramgleUseInterface  extends QuadrangleUseInterface implements drawTest{
    @Override
    //该类实现了接口,需要覆盖draw方法
    public void draw() {
        System.out.println("平行四边形draw()");
    }
    public void doAnything(){
        //覆盖父类方法
    }
}
// 定义正方形类,继承自四边形类,实现draw接口
public class SquareUseInterface extends QuadrangleUseInterface implements drawTest{

    @Override
    public void draw() {
        System.out.println("正方形的draw()方法");
    }
    public void doAnything(){}
}

 

   实例说明:

    正方形类和平行四边形类分别继承自四边形类,并实现了接口drawTest,所以需要覆盖接口中的方法,在调用draw方法时,先将子类对象向上转型为drawTest接口形式。

 

9、接口与继承

    在java中不允许多重继承,但是使用接口就可以实现多重继承,因为一个类可以同时实现多个接口,这样可以将所有需要实现的接口放在implements关键字后面用“,”隔开。

    多重继承语法如下:

    class 类名 implements 接口1,接口2,。。。,接口n

// >> TODO 接口也可以继承接口。接口可以继承多个接口,接口之间的继承要用extends
// >> TODO 接口不可以继承类
// >> TODO 继承的接口,可以有重复的方法,但是签名相同时,返回值必须完全一样,否则会有编译错误
public interface Intf3 extends Intf1, Intf2{
    void m3();
}

 

posted @ 2021-12-17 19:17  庞某人  阅读(50)  评论(0编辑  收藏  举报