JAVA基础初探(六)Object类概述(toString,equals)、JAVA多态、抽象类(abstract)、JAVA接口(interface)

部署运行你感兴趣的模型镜像

该篇博客目录

1、Object类概述(toString,equals)
2、JAVA的多态
3、JAVA抽象类(abstract)
4、JAVA的接口(interface)

一、Object类概述(toString,equals)

  • Object类是所有类的父类
  • 如果一个类没有使用extends明确标识继承另外一个类,那么该类默认继承Object类
  • Object类的方法适用于所有子类
Object类常用方法(toString,equals)
1、toString方法
  • 返回该对象的哈希code码(对象地址字符串)
  • 下面是toString的Demo

父类

package com.xxxx;

public class Animal {
    public int age=10;
    public Animal() {
        System.out.println("Animal类执行了");
        age=20;
    }
}

子类

package com.xxxx;

public class Dog extends Animal {
    public Dog() {
        System.out.println("dog执行");
    }
    public String toString() {
        return "Dog[age="+age+"]";

    }
}

测试类

package com.xxxx;

public class Initail {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Dog dog =new Dog();
        System.out.println(dog);
    }
}

//输出:
//Animal类执行了
//dog执行
//Dog[age=20]

//没有toString输出:
//Animal类执行了
//dog执行
//com.xxxx.Dog@57fa26b7
2、equals方法

比较的是对象的引用是否指向同一块内存地址
不是比较对象的成员变量的值,如果想比较值,可以重写equals方法

“==”与equals的区别
a、“==”
  • 基本类型:比较的是两个数据的值是否相等
  • 引用类型:比较的是两个对象是否指向同一块内存地址,就比较对象是否相等
b、equals
  • 引用类型:比较的是两个对象是否指向同一块内存地址,就比较对象是否相等
  • 不过equals可以重写,使得比较对象的成员变量的值是否相等
下面是关于equals重写的Demo

父类

package Obj;

public class Obj_Father {
    final private int a=10;
    public Obj_Father()
    {
    }
}

子类(重写了equals)

package Obj;

public class Obj_Child extends Obj_Father{
    public int d;
    public Obj_Child() {
        super();
    }
    //重写equals方法,使得equals比较两个对象的值,而不是比较两个对象
    @Override
    public boolean equals(Object obj) {
        if (this == obj)//先判断两个引用是否相等
            return true;
        if (obj == null)//若是空则无需比较
            return false;
        if (getClass() != obj.getClass())//通过两个对象的类型是否相同
            return false;
        Obj_Child other = (Obj_Child) obj;//因为上面已经比较了两个对象类型是否相同,所以这句转换语句也是

理所当然
        if (d != other.d)//判断两个对象的属性值是否相同
            return false;
        return true;
    }

}

测试类

package Obj;

public class Obj_main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Obj_Child obj1=new Obj_Child();
        obj1.d=10;
        Obj_Child obj2=new Obj_Child();
        obj2.d=10;
        if(obj1.equals(obj2))
        {
            System.out.println("两对象值相同");
        }
        else if(obj1==obj2)
        {
            System.out.println("两对象相同");
        }
    }

}
//输出
//两对象值相同

如果没有重写equals,则都不会输出,因为都比较了两对象是否指向同一块内存地址


二、JAVA的多态

指对象在不同时刻(比如:父子类中)表现出来的不同状态

1、使用多态的前提
  • 要有继承关系
  • 要有方法重写
  • 经常会有父类引用指向子类对象如:父类 对象名=new 子类();
2、引用多态
  • 父类引用可以指向本类对象:父类 对象名=new 父类();
  • 父类引用可以指向子类对象:父类 对象名=new 子类();

测试类Demo

package Obj;

public class Obj_main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Obj_Father obj1=new Obj_Father();//父类引用指向本类对象
        Obj_Father obj2=new Obj_Child();//父类引用指向子类对象
        }
}
3、方法多态
  • 创建本类对象时,调用的方法是本类方法
  • 创建子类对象时,调用的方法为子类重写的方法,(若没有重写,则调用继承的方法)
  • 下面是方法多态的Demo

父类

package Obj;

public class Obj_Father{
    public void print() {
        System.out.println("父类中的print方法");
    }
}

子类

package Obj;

public class Obj_Child extends Obj_Father{
    public void print(){
        System.out.println("子类中的print方法");
    }
}

测试类

package Obj;

public class Obj_main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Obj_Father obj1=new Obj_Father();//父类引用指向本类对象
        Obj_Father obj2=new Obj_Child();//父类引用指向子类对象

        obj1.print();//调用父类print方法
        obj2.print();//调用子类print方法
        //虽然obj1和obj2都是父类引用,但是指向的对象不同
    }
}

//输出
//父类中的print方法
//子类中的print方法
4、多态中引用类型转换(instanceof)
  • 向上类型转换(隐式/自动类型转换),小类型到大类型的转换(无风险)
  • 向下类型转换(强制类型转换),大类型到小类型的转换(有风险)
instanceof

格式:父类引用 instanceof 子类名

  • instanceof判断一个引用是否是某个类型或是某个类型的子类型(返回bool值)
  • instanceof运算符,解决引用对象的类型,避免类型转换的安全性问题
引用类型转换的Demo

父类

package Obj;

public class Obj_Father{
    public void print() {
        System.out.println("父类中的print方法");
    }
}

子类1

package Obj;

public class Obj_Child extends Obj_Father{
    public void print(){
        System.out.println("子类中的print方法");
    }
}

子类2

package Obj;

public class Obj_Child_second extends Obj_Father {

}

测试类

package Obj;

public class Obj_main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Obj_Child obj1=new Obj_Child();

        //利用父类的引用来指向子类对象(自动类型提升/向上类型转换)
        Obj_Father obj2=obj1;

        //将父类引用转换成子类引用,存在风险,报错
        //Obj_Child obj3=obj2;

        if(obj2 instanceof Obj_Child)
        {
            //将父类引用转换成子类引用(利用强制转换/向下类型转换)
            Obj_Child obj3=(Obj_Child)obj2;
        }else {
            System.out.println("obj2和obj3无法进行类型转换   转换成Obj_Child类型");
        }


        //将父类引用转换成Obj_Child_second子类的引用,运行时错误,因为obj2指向的是Obi_Child的对象,无法转

换成Obj_Child_second的对象
        if(obj2 instanceof Obj_Child_second)//如果obj2对象里面含有Obj_Child_second类型的元素就返回true
        {
            Obj_Child_second obj4=(Obj_Child_second)obj2;
            //1.编译时 Obj_Child_second  2.运行时 Obj_Child类型        两个类型不匹配,所以运行是出错
        }else {
            System.out.println("obj2和obj4无法进行类型转换  转换成Obj_Child_second类型");
        }

    }
}
//输出:obj2和obj4无法进行类型转换  转换成Obj_Child_second类型

三、JAVA抽象类(abstract)

1、定义

类前使用abstract关键字修饰,即为抽象类

2、抽象类应用场景
  • 某个父类只知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法(抽象类是约束子类必须有哪些方法)
  • 从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为模板,从而避免子类设计的随意性
3、抽象类的作用/目的

限制规定子类必须实现某些方法,但不关注实现细节

4、使用规则
  • abstract定义抽象类
  • abstract定义抽象方法(只声明,不实现)
  • 包含抽象方法的类一定是抽象类
  • 抽象类中可以包含普通的方法,也可以没有抽象方法
  • 抽象类不能直接创建,可以定义引用变量指向子类对象
  • 使用了abstract将会与private、final冲突
5、下面是抽象类的Demo

抽象类

package abstract_test;
//抽象类
public abstract class Tel {

    //抽象方法
    public abstract void call();
}

抽象类的子类1

package abstract_test;

public class Phone extends Tel {

    @Override
    public void call() {
        // TODO Auto-generated method stub
        System.out.println("打电话");
    }

}

抽象类的子类2

package abstract_test;

public class Newphone extends Tel {

    @Override
    public void call() {
        // TODO Auto-generated method stub
        System.out.println("新手机的打电话");
    }

}

测试类

package abstract_test;

public class main_abs {
    public static void main(String[] args)
    {
        Tel t1=new Phone();
        t1.call();

        Tel t2=new Newphone();
        t2.call();
    }
}

//输出
//打电话
//新手机的打电话
6、下面是抽象类的另一个Demo

需求:现有Shape圆形类,用Rectangle矩形和Circle圆形子类,求图形的周长和面积

Shape类

package project1;

public abstract class Shape {
    //求周长
    public abstract double Pre(double a,double b);
    public abstract double Pre(double r);
    //求面积
    public abstract double Acr(double a,double b);
    public abstract double Acr(double r);
}

Rectangle类

package project1;

public class Rectangle extends Shape {

    @Override
    public double Pre(double a,double b) {
        // TODO Auto-generated method stub
        double c=2*a+2*b;
        return c;
    }

    @Override
    public double Acr(double a,double b) {
        // TODO Auto-generated method stub
        double c=a*b;
        return c;
    }

}

Circle类

package project1;

public class Circle extends Shape {
    final double PI=3.14;
    @Override
    public double Pre(double r) {
        // TODO Auto-generated method stub
        double p=2*PI*r;
        return p;
    }

    @Override
    public double Acr(double r) {
        // TODO Auto-generated method stub
        double p=PI*r*r;
        return p;
    }

}

测试类

package project1;

public class main_Shape {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Shape rec=new Rectangle();
        Shape cir=new Circle();
        double a=1.1;
        double b=2.2;
        double r=3.3;
        double c=rec.Pre(a,b);
        double d=rec.Acr(a,b);

        double e=cir.Pre(r);
        double f=cir.Acr(r);
        System.out.println("矩形的周长:"+c);
        System.out.println("矩形的面积:"+d);
        System.out.println("圆形的周长:"+e);
        System.out.println("圆形的面积:"+f);
    }

}

四、JAVA的接口(interface)

1、接口概念
  • 接口可以理解为一种特殊的类(由常量和公共的抽象方法组成)
  • 接口其实是一个规范,用来约束类,必须实现某些方法
2、接口与抽象类的区别
  • 某个子类可以继承多个接口,但是只能继承一个类(也包括抽象类)
  • 接口中都是抽象方法,抽象类中可以有抽象方法也可以有普通方法
3、接口定义(使用interface)

格式:

[修饰符] interface 接口名[extends 父接口1,父接口2....]
{
    零个到多个常量定义;
    零个到多个抽象方法声明;
}
  • Tip1:接口就是用来被继承的,被实现的,修饰符用public
  • Tip2:接口可以多继承,继承多个父接口。但类是单继承,只能继承一个父类
4、接口中的常量与方法
  • 常量:接口中的属性都是常量,即使定义时不添加public static final修饰符,系统也会自动添加
  • 方法:接口中的方法都是抽象方法,即使定义时不添加public abstract,系统也会自动添加
5、使用接口(通过类来实现接口)(implements)

JAVA中一个类只能继承一个父类不够灵活,通过实现多个接口作为补充相当常见

格式
  • 1
    修饰符 class implements 接口1,接口2
  • 2
    修饰符 class 类名 extends 父类 implements 接口1,接口2…
    {

    }
6、下面是一个接口知识点的Demo

父类(该父类为抽象类)

package abstract_test;

public abstract class Tel {

    public abstract void call();
}

接口

package abstract_test;

public interface PlayGame {
    public void play();
}

Phone子类,不是接口的子接口

package abstract_test;

public class Phone extends Tel {

    @Override
    public void call() {
        // TODO Auto-generated method stub
        System.out.println("打电话");
    }

}

Newphone子类,既是子类也是子接口

package abstract_test;

public class Newphone extends Tel implements PlayGame {

    @Override
    public void call() {
        // TODO Auto-generated method stub
        System.out.println("新手机的打电话");
    }

    //实现接口的方法
    @Override
    public void play() {
        // TODO Auto-generated method stub
        System.out.println("Newphone可以打游戏");
    }
}

GamePhone子接口,不是子类

package abstract_test;

public class GamePhone implements PlayGame {

    @Override
    public void play() {
        // TODO Auto-generated method stub
        System.out.println("GamePhone可以打游戏");
    }

}

测试类

package abstract_test;

public class main_abs {
    public static void main(String[] args)
    {
        Tel t1=new Phone();
        t1.call();

        Tel t2=new Newphone();
        t2.call();

        PlayGame t3=new GamePhone();
        t3.play();

        PlayGame t4=new Newphone();
        t4.play();

    }
}
//输出
//打电话
//新手机的打电话
//GamePhone可以打游戏
//Newphone可以打游戏
7、使用匿名内部类实现接口

直接看下面的Demo(只需在上面的Demo中的测试类中添加语句就好)

测试类(两种方法)

package abstract_test;

public class main_abs {
    public static void main(String[] args)
    {
        Tel t1=new Phone();
        t1.call();

        Tel t2=new Newphone();
        t2.call();

        PlayGame t3=new GamePhone();
        t3.play();

        PlayGame t4=new Newphone();
        t4.play();


        ////////使用匿名内部类实现接口////////
        PlayGame t5=new PlayGame() {

            @Override
            public void play() {
                // TODO Auto-generated method stub
                System.out.println("使用匿名内部类实现接口");
            }

        };//别忘记分号
        t5.play();

        //第二种方法
        new PlayGame() {

            @Override
            public void play() {
                // TODO Auto-generated method stub
                System.out.println("使用匿名内部类实现接口第二种方法");
            }
        }.play();


    }
}
//输出:
//打电话
//新手机的打电话
//GamePhone可以打游戏
//Newphone可以打游戏
//使用匿名内部类实现接口
//使用匿名内部类实现接口第二种方法

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值