java面向对象基础进阶day02

方法重写 

        父子类继承关系中,当子类需要父类的功能,而继承的方法不能完全满足子类的需求,子类里面有特殊的功能,此时可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。 

方法重写细节

  • 前提:父子类继承关系中
  • 子类新增方法,和从父类继承的方法,方法名完全相同
  • 两个方法的参数列表完全相同
  • 重写方法的访问权限修饰符可以被扩大,但是不能被缩小
  • public > protected > default > private
  • 方法的返回类型可以相同,也可以不同
  • 方法抛出异常类型的范围可以被缩小,但是不能被扩大 

案例: 

//定义父类:员工
class Employee {
    //工号、姓名
    private String id;
    private String name;
    public Employee() {}
    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }
    public void doWork() {
        System.out.println("员工开始工作...");
    }
}
    //定义子类:程序员
class Programmer extends Employee {
    //等级:初级、中级、高级、资深
    private String grade;
    public Programmer() {
        //默认会调用父类无参构造器
    //super();
    }
    public Programmer(String id,String name,String grade) {
        //显式调用父类构造器
        super(id,name);
        this.grade = grade;
    }
    //重写
    @Override
    public void doWork() {
        //super.doWork();
        System.out.println("我是程序员,级别为" + grade + ", 开始工作:写代码");
        }
    }
    //定义子类:经理
class Manager extends Employee {
    //奖金
    private double bonus;
    public Manager() {
        super();
    }
    public Manager(String id,String name,double bonus) {
        super(id,name);
    this.bonus = bonus;
    }
    //重写方法
    @Override
    public void doWork() {
        System.out.println("我是经理,有津贴" + bonus + ", 开始工作:安排部门员工任务");
    }
}
    //测试类
public class Test06_Override {
    public static void main(String[] args) {
    //父类对象 调用 doWork方法
        Employee e = new Employee("008", "larry");
        e.doWork();
        System.out.println("------------");
        //程序员子类对象 调用 重写方法
        Programmer p = new Programmer("010", "kevin", "初级");
        p.doWork();
        System.out.println("------------");
        //经理子类 调用 重写方法
        Manager m = new Manager("006", "robin", 201.5);
        m.doWork();
    }
}

运行结果 java面向对象基础进阶day02_第1张图片

注意事项

  1. 父类中的静态方法(属于类方法)不能被子类重写 static静态方法算不上重写,它是属于父类所独有的,只是书写格式上跟重写相似  。
  2. 父类中的私有方法(未被继承)不能被子类重写

重写和重载的区别 

        重写发生在子父类中  重载发生在一个类中  

        重写规则:为了覆盖(重写)父类的方法      

  1.  重写要求权限不能缩小 访问修饰符可以扩大 不能被缩小   public>protected>default>private 
  2. 两个方法的方法名 参数列表完全相同      
  3. 要求返回值的返回类型可以相同也可以不同 一般相同      
  4. 方法抛出异常类型的范围可以被缩小 但是不能够被扩大          

        一般情况下,子类进行方法重写时,最好方法的声明完全一致

结论:

        子类继承父类,在调用方法的时候,如果子类中没用重写,那么调用      从父类继承的方法,如果子类重写了这个方法,那么调用到子类重写的方法。( 非常重要 ) 

多态 

多态的前提 

  • 子类继承父类
  • 子类重写父类中的方法
  • 父类的引用指向子类对象 

案例: 

package com.briup.day08;

/**
 * @author 谭梦寻
 * @version 1.1
 */
public class Test01 {

/*
        多态前提:
            子类继承父类
            子类重写父类中的方法
            父类的引用指向子类对象
        注意:
            当调用属性时,编译和运行都看左边 --》属性也没有重写
            当调用非重写方法时,编译和运行都看左边
            当调用重写方法时,编译看左边 运行看右边
*/
    public static void main(String[] args) {
//        1 面向对象创建字符串对象 通过构造器创建对象
        String s = new String("abc");
        String s2 = new String("abc");
/*
        System.out.println(s.equals(s2));//true
        不是一个对象 但是是String类型 比较长度后比较内容 都满足也会返回true
*/
        System.out.println(s.equals(s2));//true String里面重写了Object中的equals方法
        System.out.println(s==s2);//false 两个引用是否指向同一个对象
        Integer i = new Integer(1);
        Integer i2 = new Integer(1);
        System.out.println(i.equals(i2));// true 同理于String

//        多态 父类型的引用 指向子类型对象 --> 看等号右边
//        隐式转换 大类型 = 小类型 long a = 1;
        SuperName superName = new SubName();
        superName.method();//son
        superName.method2();//Father2
        SuperName superName1 = new SuperName();
//        superName.method3(); //私有方法无法调用 也无法继承
//        superName.method4();//报错

        /*
        子类对象调用该方法 引用的类型是父类型
        如果是重写 编译看左边 运行看右边
        即:是否能通过编译 由父类决定 父类引用无法调用子类私有方法
            运行结果看子类
        如果不是重写 编译和运行都是看左边
         */

        SuperName b = new SubName();
        Object o = new SuperName();
        o = b;//隐式转换
        b = (SubName) o;//强制转换 等价于SuperName b = o = new SubName();
        String s1 = new String("abc");
//        s1 = (String) o;//编译没问题 运行报错 ClassCastException

/*
    instanceof
        对象类型的比较
        判断引用名实际指向的对象,其所属类型是否为右边的类型名,
        返回boolean类型结果
*/
        Object b2 = new SubName();
        System.out.println(b2 instanceof String); //false
        System.out.println(b2 instanceof SubName); //true
        System.out.println(b2 instanceof Object); //true
    }
}
class SuperName {
    public static void main(String[] args) {
        SuperName superName = new SubName();
        superName.method();//son
        superName.method2();//Father2
        SuperName superName1 = new SuperName();
        superName.method3(); //Father3
//        superName.method4();//报错
    }
    public void method() {
        System.out.println("Father");
    }
    public static void method2() {
        System.out.println("Father2");
    }
    private void method3() {
        System.out.println("Father3");
    }
}
class SubName extends SuperName{
    public void method() {
        System.out.println("Son");
    }
    public static void method2() {
        System.out.println("Son2");
    }
    private void method3() {
        System.out.println("Son3");
    }
    public void method4() {
        System.out.println("Son4");
    }
}

注意:    

  • 当调用属性时,编译和运行都看左边 --》属性也没有重写    
  • 当调用非重写方法时,编译和运行都看左边    
  • 当调用重写方法时,编译看左边 运行看右边 

向上转型(隐式转换)

        父类引用指向子类对象,多态部分我们已经大量使用
        例如, Person p = new Student();


向下转型(显式转换)

        子类引用指向父类对象
        格式: 子类型 对象名 = (子类型)父类引用;
        前提:父类对象本身就是子类类型
        Person p = new Student();
        Student s = (Student)p; //向下转型
注意事项:先有向上转型,然后才能有向下转型

==和equals的区别 

基本数据类型: 1==2 true == false 比较的数值 二进制代码是否相同

引用数据类型: equals 比较的两个引用是否实质相同一个对象 比较地址值(哈希值) equals 只能比较引用类型 即对象 如果equals没有被重写  就使用时Object类中提供的逻辑 比较两个引用的地址值是否相等 如果equals被重写了 就是重写后的逻辑 。

总结:==用于比较基本数据类型,否则会报类似于Operator '==' cannot be applied to 'java.lang.String错误。equals用于比较引用类型。

你可能感兴趣的:(java,开发语言)