权限修饰符、方法重写、多态、Object类、abstract抽象方法

1.权限修饰符

被不同权限修饰符修饰的内容其能够被使用的范围是不同的:

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

以下几点需要值得注意:

  • 一般情况下使用最多的是private以及public;
  • 能够修饰类的权限修饰符:public,default(默认省略不写);
  • 都是成员修饰符,只能修饰成员,不能修饰局部;
  • 不能外部调用一个作用域中的局部内容(局部变量);

在具有子父级继承关系的类具有以下几点需要注意:

  • 不同包下的子类,私有的内容能够被继承但不能被使用,因为无权使用。
  • 在不同包下的子类中,如果想要使用父类中被protected修饰的成员,需要通过继承关系使用(直接在子类使用有权限的父类成员或通过子类对象使用),不能通过父类对象使用。
//父类
public class Decorate {
    public int a;//公共类型变量
    protected int b;//受保护的变量
    int c;//默认类型的变量
    private int d;//私有化的变量
    //公共方法
    public void functiona(){
        System.out.println("public");
    }
    //受保护的方法
    protected void functionb(){
        System.out.println("protected");
    }
    //默认类型方法
    void functionc(){
        System.out.println("default");
    }
    //私有化的方法
    private void functiond(){
        System.out.println("private");
    }
}
//同包下的子类
public class Test extends Decorate{
    public static void main(String[] args) {
        Test test = new Test();
        System.out.println(test.a);
        test.functiona();
        test.functionb();
        test.functionc();
        //test.functiond();  父类的私有化方法无法使用

    }
    public void Test2(){
        System.out.println(a);
    }
}

2.方法的重写

2.1重写与重载的区别

重载:

  • 同一个类;
  • 方法名相同;
  • 参数列表不同|方法签名不同;

重写:

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

2.2重写的运用

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

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

注意:子类一旦重写父类中的方法,就是对父类当中方法屏蔽。

检查是否为重写方法的工具:

  • @override强制检查是否存在重写
  • 工具中方法的左侧有提示

满足重写的情况:

  • ==:方法签名完全相等
  • <=:返回值类型为基本数据类型则完全相等,引用数据类型,子类方法返回值类型<=父类返回值类型
  • ’>=权限修饰符,子类方法修饰符>=父类方法权限修饰符

不能被重写的方法:

  • 被private关键字修饰的方法不能被重写
  • 被final关键字修饰的方法不能被重写
  • 被static关键字修饰的方法不能被重写,当子类出现与父类静态方法同名的方法时,子类的同名方法也是静态,否则会报错,且不属于方法重写
//测试类
public class Test {
    public static void main(String[] args) {
        Son son  = new Son();
        son.talk();
        son.name="子类";
        son.work();
    }
}
//租父类
public class GrandF {
    public void work(){

    }
}
//父类  继承租父类
public class Fa extends GrandF{
    public String name;
    public int age;
    public void talk(){
        System.out.println("父类");
    }
    public  void sleep(){
        System.out.println("休息");
    }
}
//子类	继承父类
public class Son extends Fa{
    public void talk(){
        System.out.println("方法重写子类");
    }
    @Override//方法重写
    public void sleep(){
        System.out.println("休息2");
    }
}

3.多态

3.1多态的体现

多态即一种事物的多种表现形式|多种形态。

多态的最终体现:父类的引用指向子类的对象。

多态的前提:继承|实现

多态的优点:多态可以让程序变得更加灵活,便于后期维护。

3.2多态的使用

当父类类型的引用调用成员时:

成员变量:编译运行看父类|左边|类型

成员方法:编译看父类|左边|类型

​ 运行找子类|右边|类型

注:当通过父类的引用调用成员方法时,如果子类有重写方法就调用重写,没有就调用父类,如果多态不配合方法重写,多态就没有意义。

//测试类
public class TestDuotai {
    public static void main(String[] args) {
        Father fa = new Son();//父类引用指向子类对象
        System.out.println(fa.name);
        fa.talk();
    }
}
//父类
class Father {
    String name = "father";
    public void talk(){
        System.out.println("这是父类");
    }
}
//子类
class Son extends Father{
    String name = "son";
    //多态如果不配合方法的重写就没有意义
    public void talk(){
        System.out.println("这是子类");
    }
}

4.引用类的转型

引用数据类型的类型提升与基本数据类型的类型转换相似。

向上转型:即自动类型提升

​ 父类类型 引用 = new 子类类型();

向下转型:强制类型转换

​ 从大到小——>从父类到子类

​ 小范围类型 变量 = (小范围类型)大范围类型的数据;

在向下转型过程中可能遇到类型转换异常:

引用instanceof:判断前面的引用是否指向后面类的对象,或者后面类型子类的对象,如果是返回true,如果不是返回false。

值得注意的是:多态引用不能调用子类中独有的方法,需要向下转型。

//测试类
public class CastTest {
    public static void main(String[] args) {
        Fu fu = new Son();//多态
        Bro bro = new Bro();

        if(fu instanceof Fu){//判断fu引用是否是Fu类型的对象
            System.out.println("true");
        }else{
            System.out.println("false");
        }
    }
}
//父类
class Fu{
    public void teach(){
        System.out.println("教育");
    }
    public void study(){
        System.out.println("学习");
    }
}
//子类
class Son extends Fu {
    public void play(){
        System.out.println("玩");
    }
}
//兄弟类  继承了父类
class Bro extends Fu{
    public void search(){
        System.out.println("调查");
    }
}

5.Object类

​ Object类是java中所有类的父类,所有的类都会直接或间接的继承自Object类,如果没有显示的继承自某个类,默认会继承Object。

5.1equals方法

​ equals是比较两个对象是否相等,如果想要实现比较对象内容,而非地址值,需要在子类中重写equals方法,需要自己实现比较内容(成员属性的值)。

​ 如果想要实现比较对象内容,而非地址,需要在子类中重写equals方法。

Object类中,equals的默认方法:

  public boolean equals(Object obj) {
            return (this == obj);
        }

==与equals的差别:

==:比较基本数据类型,比较数据值;比较引用数据类型时是比较两个对象的地址是否相等

重写的equals可以比较两个引用数据类型对象的值。

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

//测试类
public class OverrideEquals {
    //主方法
    public static void main(String[] args) {

        Person p1 = new Person("小白",18,150);
        Person p2 = new Person("小白",18,150);
        //调用重写的equals方法
        System.out.println(p1.equals(p2));
    }
}
//人类
class Person{
//成员变量
    public String name;
    public int age;
    public int id;
    public Person(){
    }
//有参构造
    public Person(String name,int age,int id){
        this.name = name;
        this.age = age;
        this.id = id;
    }
    //成员方法
    public void getInfo(){
        System.out.println("姓名:"+this.name+",年龄:"+this.age+",身份证号:"+id);
    }
//人类中对equals重写
    public boolean equals(Object obj) {
        int num1 = this.id;
        if(obj instanceof Person){
            Person pp = (Person) obj;
            if(pp.id == num1){
                return true;
            }
        }
        return false;
    }
}

5.2toString方法

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

注意:

  • 当打印一个对象的引用的时候,默认会调用toString,打印的是当前对象调用了toString之后的返回值;
  • 以后所定义的javabean,规范: 都会默认提供一个toString以及equals的重写;
public class ToStringDemo02 {
    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = new Student();

        s1.name = "zhangsan";
        s1.age = 19;

        System.out.println(s1);
        System.out.println(s1.toString());
    }
}

class Student{
    public String name;
    public int age;

    //需求:打印对象引用时候,输出当前对象的所有成员变量的值
    public String toString(){
        return name+"-->"+age;
    }
}

6.abstract抽象方法

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

抽象类:被abstract修饰的类。

注:1.抽象类不能够实例化
2.抽象方法必须存在抽象类中
3.抽象类中可以存在抽象方法,可以存在普通的具体方法,可以存在成员,构造器…
4.抽象方法必须要被重写才能使用
5.抽象方法只要被重写就可以使用,不需要再次重写,可以根据需求进行重写
6.抽象类使用: 通过具体子类的对象调用
1.普通的子类: 需要重写所有抽象方法+按需新增
2.抽象子类: 按需重写抽象方法+按需新增
7.abstract不能与private,static,final,native同时存在

抽象类的使用:通过具体子类的对象调用

​ 普通子类需要重写所有抽象方法+按需新增

​ 抽象子类按需重写,按需新增。

abstract不能与private、static、final、native同时存在

public class AbsTest {
    public static void main(String[] args) {
        //抽象类不能实例化
        //Develop de = new Develop();

        //具体子类的使用
        Java java = new Java();
        java.work1();
        java.work2();
        java.xingxiang();
        java.sleep();

        Web2 web = new Web2();
        web.test();
        web.work2();
        web.sleep();
        web.work1();

        //抽象类的多态 : 向上转型
        //只能调用develop类中的功能
        Develop d = new Java();
        d = new Web2();


    }
}
public class Java extends Develop{
    //对父类中继承的抽象方法进行重写实现
    @Override
    public void work1() {
        System.out.println("JAVA按照规矩办事!!!");
    }

    @Override
    public void work2() {
        System.out.println("JAVA做后端开发...");
    }

    //形象  -->新增方法
    public void xingxiang(){
        System.out.println("没头发了!!!!又该植发了!!!!!");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值