JavaSe基础:面向对象3(权限修饰符,方法的重写,多态,类型转换,equals方法,toString方法,abstract类)

JavaSe基础:面向对象3

1. 权限修饰符

权限修饰符的作用是指定内容能够被使用的范围,具体如下:

本类同包类不同包子类不同包下的其他类
私有的private
默认的default
受保护的protected
公共的public

注:

  • 使用最多的是private和public
  • 能够修饰类的权限修饰符:public,default(默认的省略不写)
  • 都是成员修饰符,只能修饰成员,不能修饰局部
  • 在不同包下的子类,如果想要使用父类中被protected修饰的成员,需要通过继承关系使用(直接在子类使用有权限的父类成员,或者通过子类对象使用),不能通过父类对象使用

例:

//测试本类下
public class ModifierTest {
    //静态变量
    private static String privateTest = "private";
    static String defaultTest = "default";
    protected static String protectedTest = "protected";
    public static String publicTest = "public";
    //成员变量
    private String privateTest01 = "private";
    String defaultTest01 = "default";
    protected String protectedTest01 = "protected";
    public String publicTest01 = "public";
    
    public static void main(String[] args) {
        //测试静态变量
        System.out.println(privateTest);
        System.out.println(defaultTest);
        System.out.println(protectedTest);
        System.out.println(publicTest);
        //测试成员变量
        ModifierTest m1 = new ModifierTest();
        System.out.println(m1.privateTest01);
        System.out.println(m1.defaultTest01);
        System.out.println(m1.protectedTest01);
        System.out.println(m1.publicTest01);
    }
}
//测试同包下
public class ModifierTest02 {
    public static void main(String[] args) {
        //测试静态变量
        //System.out.println(ModifyTest.privateTest); private修饰的无法使用
        System.out.println(ModifierTest.defaultTest);
        System.out.println(ModifierTest.protectedTest);
        System.out.println(ModifierTest.publicTest);
        //测试成员变量
        ModifierTest m2 = new ModifierTest();
        //System.out.println(m2.privateTest01); private修饰的无法使用
        System.out.println(m2.defaultTest01);
        System.out.println(m2.protectedTest01);
        System.out.println(m2.publicTest01);
    }
}
//测试不同包下子类
public class ModifierTest03 extends ModifierTest {
    public static void main(String[] args) {
        //测试静态变量
        //System.out.println(privateTest); private修饰的无法使用
        //System.out.println(defaultTest); default修饰的无法使用
        System.out.println(protectedTest);
        System.out.println(publicTest);
        //测试成员变量
        ModifierTest03 m3 = new ModifierTest03();
        //System.out.println(m3.privateTest01); private修饰的无法使用
        //System.out.println(m3.defaultTest01); default修饰的无法使用
        System.out.println(m3.protectedTest01);
        System.out.println(m3.publicTest01);
    }
}
//测试不同包下其他类
public class ModifierTest04 {
    public static void main(String[] args) {
        //测试静态变量
        //System.out.println(ModifyTest.privateTest); private修饰的无法使用
        //System.out.println(ModifierTest.defaultTest); default修饰的无法使用
        //System.out.println(ModifierTest.protectedTest); protected修饰的无法使用
        System.out.println(ModifierTest.publicTest);
        //测试成员变量
        ModifierTest m4 = new ModifierTest();
        //System.out.println(m4.privateTest01); private修饰的无法使用
        //System.out.println(m4.defaultTest01); default修饰的无法使用
        //System.out.println(m4.protectedTest01); protected修饰的无法使用
        System.out.println(m4.publicTest01);
    }
}

2. 方法的重写Override

重写是方法的特性,可以重新定义方法体,需要满足以下条件:

  • 不同的两个类
  • 继承关系
  • 方法签名(方法名+参数列表)相同

应用场景:在子类继承父类后,继承了一系列功能方法,有些功能的实现不满意,可以进行功能的重写。

子类一旦重写方法,子类对象调用的时候,采用就近原则;子类对象调用功能时,子类存在找子类,子类没有找父类。

注:子类一旦重写父类中的方法,就会对父类方法进行屏蔽

不能被重写的方法:

  • 被private关键字修饰的方法不能被重写
  • 被final关键字修饰的方法不能被重写
  • 被static关键字修饰的方法不能被重写,当子类中出现与父类静态方法同名的方法时,子类的同名方法也要是静态的,否则会报错,但是不是重写方法

例:

//测试方法的重写
public class OverrideTest {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.speak();
    }
}
//定义父类
class Fu{
    public void speak(){
        System.out.println("我是父类");
    }
}
//定义子类
class Zi extends Fu{
    //方法的重写
    @Override
    public void speak(){
        System.out.println("我是子类");
    }
}

3. 多态Polymorphism

多态是一种事物的多种形态或多种表现形式,多态的最终体现是父类的引用指向子类的对象。多态的前提是继承,优点是可以让程序变得更加灵活,便于后期维护。

多态使用过程中,当父类类型的引用调用成员时,成员变量和成员方法编译看父类,成员方法运行找子类。当通过父类的引用调用成员方法时,如果子类有重写方法就调用重写的,如果没有就找父类。

例:

//测试多态
public class PolymorphismTest {
    public static void main(String[] args) {
        //多态的体现
        FuLei fu = new ZiLei();
        System.out.println(fu.name);//打印父类的name属性
        fu.test();//调用子类的重写方法
    }
}
//定义父类
class FuLei{
    String name = "张三";
    public void test(){
        System.out.println("我是父类");
    }
}
//定义子类
class ZiLei extends FuLei{
    String name = "李四";
    @Override
    public void test(){
        System.out.println("我是子类");
    }
}

4. 类型转换Cast

引用数据类型的转型,分为以下两种:

  • 向上转型:即自动类型提升,多态就是向上转型的体现
  • 向下转型:即强制类型转换,具体语法是 “小范围类型 变量 = (小范围类型) 大范围类型的数据”

注:

  • 多态引用不能调用子类中独有的方法,对子类新增功能不可见
  • 如果想要调用子类的独有方法,需要向下转型
  • 如果向下转型想要保证不出现类型转换异常,可以使用instanceof进行提前判断,instanceof是用来判断前面的引用是否指向后面类型的对象,或者是否指向后面类型子类的对象,如果是返回true,不是返回false

例:

//测试类型转换
public class CastTest {
    public static void main(String[] args) {
        Father father = new Son1();
        System.out.println(father.name);//父亲
        father.speak();//我是大儿子
        //判断引用是否为Son1类对象
        if (father instanceof Son1){
            Son1 son1 = (Son1) father;
            System.out.println(son1.name);//大儿子
            son1.speak();//我是大儿子
            son1.play();//打篮球
        }
        //测试instanceof的使用
        System.out.println(father instanceof Father);//true
        System.out.println(father instanceof Son1);//true
        System.out.println(father instanceof Son2);//false
    }
}
//定义父类
class Father{
    String name = "父亲";

    void speak(){
        System.out.println("我是父亲");
    }
}
//定义子类1
class Son1 extends Father{
    String name  = "大儿子";
    //方法重写
    @Override
    void speak(){
        System.out.println("我是大儿子");
    }

    void play(){
        System.out.println("打篮球");
    }
}
//定义子类2
class Son2 extends Father{
    String name  = "二儿子";
    //方法重写
    @Override
    void speak(){
        System.out.println("我是二儿子");
    }

    void play(){
        System.out.println("踢足球");
    }
}

5. Object类

object类是java的老祖宗类,存在于java.lang包下,不需要导包,是java中所有类的父类,有两个重点方法,一个是equals方法,一个是toString方法。

5.1 equals方法

equals方法是用来比较两个对象是否相等的方法(默认是使用==进行比较,比较的是对象地址),如果想要实现比较对象内容而非地址值时,需要在子类中重写equals方法,实现比较成员属性的值。

注:

  • 通过java实现功能就是为了处理生活中的业务,会以生活中具体的逻辑考虑问题,认为两个对象如果所有成员属性的值都想等,就应该是一个对象
  • 在java中只要通过new关键字创建的对象,无论成员属性值是否相等,地址都不相等,如果比较地址的话都不相等,所以使用引用数据类型对象的时候,不让它默认比较地址,手动让它实现比较内容

例:

//测试重写equals方法
public class EqualsOverride {
    public static void main(String[] args) {
        Person p1 = new Person("张三",18);
        Person p2 = new Person("张三",18);
        //比较两个对象的地址
        System.out.println(p1 == p2);//false
        //重写equals方法变成比较两个对象的属性
        System.out.println(p1.equals(p2));//true
    }
}
//定义类
class Person{
    public String name;
    public int age;
    public Person() {}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //重写equals方法
    @Override
    public boolean equals(Object obj){
        String str1 = this.name;
        int a1 = this.age;
        if(obj instanceof Person){
            String str2 = ((Person) obj).name;
            int a2 = ((Person) obj).age;
            if (str1.equals(str2) && a1 == a2){
                return true;
            }
        }
        return false;
    }
}

5.2 toString方法

toString方法是以字符串的形式表示当前对象。object类中的toString方法默认返回当前对象类型的包名.类名@十六进制。如果想要打印对象的成员变量的值不想打印对象地址,需要在子类中对toString方法进行重写。

注:

  • 当打印一个对象的引用的时,默认会调用toString,打印的是当前对象调用了toString之后的返回值
  • 以后所定义的javabean规范:默认提供一个toString以及equals方法的重写

例:

//测试重写toString方法
public class ToStringOverride {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.name = "张三";
        stu.age = 19;
        System.out.println(stu);//默认调用toString方法  Student{张三,19}
    }
}
//定义类
class Student{
    public String name;
    public int age;
	//重写toString方法
    @Override
    public String toString() {
        return "Student{"+name+","+age+"}";
    }
}

6. Abstract类

被abstract修饰的类为抽象类,被abstract修饰的方法为抽象方法。抽象方法可以没有方法体,但必须存在于抽象类中。

注:

  • 抽象类不能够实例化
  • 抽象方法必须存在抽象类中
  • 抽象类中可以存在抽象方法,可以存在普通的具体方法,可以存在成员,构造器
  • 抽象方法必须要被重写才能使用
  • 抽象方法只要被重写就可以使用,不需要再次重写,可以根据需求进行重写
  • 抽象类使用:通过具体子类的对象调用。如果是普通的子类,需要重写所有抽象方法以及按需新增;如果是抽象子类,按需重写抽象方法以及按需新增
  • abstract不能与private,static,final,native关键字同时存在

例:

//测试抽象类
public class TestAbstract {
    public static void main(String[] args) {
        Employee e = new Employee();
        e.work();
        e.work1();
    }
}
//定义抽象类
abstract class Job{
    abstract void work();
}
//定义抽象类继承抽象类
abstract class Designer extends Job{
    abstract void work1();
}
//定义类继承抽象类
class Employee extends Designer{
    //重写抽象方法
    @Override
    void work() {
        System.out.println("我是做设计的员工");
    }
	//重写抽象方法
    @Override
    void work1() {
        System.out.println("我是做建筑设计的员工");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值