Java新手小白入门篇 Java面向对象(四)

本文详细介绍了Java中的向上造型概念,包括超类型引用指向派生类对象及其方法调用规则。同时,讲解了方法的重写,强调了重写时的签名匹配原则和调用规则。此外,还探讨了Java中的访问控制修饰符、static关键字的使用场景,以及静态变量和静态方法的特性。最后,通过实例解析了静态变量在多个对象间的共享行为,并给出了相关练习题以巩固知识。

一、向上造型(下) 
1. 超类型的引用指向派生类的对象 
public class Test{
    public static void main(String[] args) {
        //超类型(父类)    引用    指向      对象(派生类)子类
        Aoo             o         =             new Boo();
    }
}
class Aoo{} //超类
class Boo extends Aoo{} //派生类
 
2. 能点出来什么,看引用的类型 
public class Test{
    public static void main(String[] args) {
        //超类型(父类)    引用    指向     对象(派生类)子类
        Aoo             o         =             new Boo();
        o.sayHi(); // Aoo的sayHi方法
        // o.sayHello(); // 报错,引用只能调用Aoo的方法
    }
}
class Aoo{ // 超类
    void sayHi() {
        System.out.println("Aoo的sayHi方法");
    }
}
class Boo extends Aoo{ // 派生类
    void sayHello() {
        System.out.println("Boo的sayHello方法");
    }


3. 如果父类的方法被子类所重写,调用的就是子类的方法(看对象的类型) 
 

如不了解 方法的重写,请先参考学习下面重写的知识点 
public class Test{
    public static void main(String[] args) {
        //超类型(父类)    引用    指向     对象(派生类)子类
        Aoo             o         =             new Boo();
        // 由于sayHi方法被子类重写,实际调用的就是子类的方法
        o.sayHi(); // Boo的重写后的sayHi方法
        // o.sayHello(); // 报错,引用只能调用Aoo的方法
    }
}
class Aoo{ // 超类
    void sayHi() {
        System.out.println("Aoo的sayHi方法");
    }
}
class Boo extends Aoo{ // 派生类
    // 方法的重写
    void sayHi() {
        System.out.println("Boo的重写后的sayHi方法");
    }
    void sayHello() {
        System.out.println("Boo的sayHello方法");
    }


二、方法的重写(Override) 
1. 定义 
 
 重写(覆盖):父子类中,子类方法与父类方法的名称相同,参数列表也相同我们称之为方法的重写 方法的签名 = 方法名称 + 参数列表 我们又称:父子类中,子类与父类方法的签名相同的方法叫方法的重写 当父类提供的方法不能满足你的业务需求时,需要重写 
 在这里插入图片描述
 
三、访问控制修饰符 

类的访问控制权限只能是 public 和 默认的

类中成员的访问权限四种都可以使用 


四、static 关键字 
 
 static 是Java中的一个关键字,表示静态的意思。表示全局唯一的,一经改变,都进行改变 
 
1. staitc 使用场景 
1.1 修饰变量:静态变量 
静态变量,又称类变量,由static修饰属于类,存储的方法区中,只有一份常常通过类名点的方式来调用何时用:所有对象所共享的数据(图片、音频、视频)static不能修饰局部变量 
public  class Animal { //动物
    public int age = 1;
    public static double weight = 100; //体重
    public void sayHi() {
        this.age = age + 1;
        System.out.println(age);
        this.weight = weight + 5;
        System.out.println(weight);
        System.out.println(age + "/" + weight);
    }
    public static void main(String[] args) {
        Animal a = new Animal();
        a.sayHi();// 2/105.0
        Animal a1 = new Animal();
        a1.sayHi();// 2/110.0
        Animal a2 = new Animal();
        a2.sayHi();// 2/115.0
    }    
}
 在这里插入图片描述
1.2 修饰方法:静态方法 
由static修饰属于类,存储的方法区中,只有一份常常通过类名点的方式来调用静态方法中没有隐式的this传递,静态方法中不能直接访问实例成员何时用:方法的操作与对象无关----方法中不需要访问对象的属性或行为 
public class Animal{
    public static String name;//静态变量
    int age;
    public void sayHi() {
        this.name = "动物";
        this.age = 2;
        sayHello(); // 在sayHi这个普通方法中能直接调用sayHello这种实例成员
    }
    public void sayHello() {
    }
    public static void say() {
        Animal.name = " ";
        Animal a = new Animal();
        // age = 18; // 报错,在say这个静态方法中不能直接访问实例成员,需要通过new对象打点的方式访问
        a.age = 5;
        // sayHello(); // 报错,在say这个静态方法中不能直接访问实例成员,需要通过new对象打点的方式访问
        a.sayHello();
    }
}

1.3 修饰代码块:静态代码块 
由static修饰属于类,在类被加载期间自动执行,类只被加载一次,所以静态块也只执行一次何时用:加载/初始化静态资源(图片、音频、视频等) 
public class Animal{
    static {
        System.out.println("静态代码块1");
    }
    static {
        System.out.println("静态代码块2");
    }
    {
        System.out.println("构造代码块");
    }
    Animal(){
        System.out.println("无参构造");
    }
    
    public static void main(String[] args) {//有输出结果吗?//是什么?    
        // 静态代码块1 -> 静态代码块2 -> 构造代码块 -> 无参构造
        Animal a1 = new Animal();
        // 构造代码块 -> 无参构造
        Animal a2 = new Animal();
    }
}
五、拓展 
1. 重载和重写的区别 
1.1 概念 
重载(overload) 
  发生在同一个类中,方法名相同,参数列表不同,方法体不同与返回值类型无关编译期绑定 重写(override) 
  发生在父子类中,方法名称相同,参数列表相同(方法名称+参数列表=方法的签名)方法体不同重写遵循两同两小一大 
    1)两同:方法名相同,参数列表相同(方法的签名)2)两小:(返回值类型、异常、访问权限) 
      A. 子类方法的返回值小于等于父类方法的返回值 
        a. void/基本类型返回值必须相同b. 引用类型的返回值小于等于父类的返回值 B. 子类方法抛出的异常小于或等于超类的方法抛出的异常 3)一大:子类方法的访问权限大于或等于父类方法的 运行期绑定  
1.2 案例 
重写: 
 两小 
  子类方法的返回值小于等于父类方法的返回值 
     void/基本类型返回值必须相同 
       void class Aoo{//超类
    void sayHi() {}    
}
class Boo extends Aoo{//派生类
    void sayHi() {}
}
123456  基本类型 class Aoo{//超类
    int sayHi() {return 1;}    
}
class Boo extends Aoo{//派生类
    int sayH() {return 2;}//是重写
}class Aoo{//超类
    int sayHi() {return 1;}    
}
class Boo extends Aoo{//派生类
    double sayHi(){return 4.0;}//不是重写
}
123456   引用类型的返回值小于等于父类的返回值 
       小于指的是父类方法类型的子类,或者子类的子类,等于是指和父类方法类型相同 public class Father {}
public class Son extends Father{}

 

public class Aoo {
    Father getObject() {
        System.out.println("Aoo");
        return new Father();
    }
}
public class Boo extends Aoo{
    Father getObject() {
        System.out.println("Boo");
        return new Father();
    }
}
public class Coo extends Aoo{
    Son getObject() {
        System.out.println("Coo");
        return new Son();
    }
}

public class Demo {
    public static void main(String[] args) {
        Aoo o1 = new Boo();
        o1.getObject(); // Boo
        Aoo o2 = new Coo();
        o2.getObject(); // Coo
    }
}
    一大 在这里插入图片描述
  派生类方法的访问权限大于或等于超类方法的   

 


注意:构造方法不能重写,声明为 final 的方法不能被重写,声明为 static 的方法不能被重写,但是可以被再次声明 
2. 变量的划分 
 
 变量按照作用域来划分:a.成员变量 b.局部变量 
 
 在这里插入图片描述
 成员变量 
  实例变量 
    没有static修饰,属于对象的,存储在堆中,有几个对象就有几份(new),通过对象名点来访问 静态变量(类变量) 
    由static修饰,属于类的,存储在方法区中,只有一份,常常通过类名点来访问 我们常常说实例变量属于对象,静态变量属于类。  

在这里插入图片描述

 

 局部变量 
  形参:方法签名中定义的变量代码块(语句块):{ }  
六、练习题 
1. 练习题 
1.1 向上造型,重写 
应用知识点: 
能点出来什么,看引用的类型重写的方法被调用时,看对象的类型 
1.1.1 第一题 
public class Test {
    public static void main(String[] args) {
        Aoo o = new Boo();
        o.sayHi();//输出的是什么?为什么?
        o.sayHello("李四");//输出的是什么?为什么?
    }
}
class Aoo{//超类
    String name;
    Aoo(){}
    Aoo(String name){
        this.name = name;
        System.out.println("超类");
    }
    void sayHi() {
        System.out.println("Aoo的方法");
    }
    void sayHello(String name){
        System.out.println("大家好我叫"+name);
    }
}
class Boo extends Aoo{//派生类
    int age;
    Boo(){}
    Boo(String name,int age){
        super(name);
        this.age = age;
        System.out.println("派生类");
    }
    void sayHi() {
        System.out.println("Boo的方法");
    }
    void sayHello(String name,int age){
        System.out.println("大家好我叫"+name + ",今年"+age+"岁了");
    }
}

1.1.2 第二题 
public class Test {
    public static void main(String[] args) {
        Aoo o = new Boo();
        o.sayHi();//输出的是什么?为什么?
        o.sayHello("李四");//输出的是什么?为什么?
    }
}
class Aoo{//超类
    String name;
    Aoo(){}
    Aoo(String name){
        this.name = name;
        System.out.println("超类");
    }
    void sayHi() {
        System.out.println("Aoo的方法");
    }
    void sayHello(String name){
        System.out.println("大家好我叫"+name);
    }
}
class Boo extends Aoo{//派生类
    int age;
    Boo(){}
    Boo(String name,int age){
        super(name);
        this.age = age;
        System.out.println("派生类");
    }
    void sayHi() {
        System.out.println("Boo的方法");
    }
    void sayHello(String name){
        System.out.println("大家好我叫"+name + ",今年"+age+"岁了");
    }
}

1.1.3 第三题 
public class Test {
    public static void main(String[] args) {
        Aoo o = new Boo("张三",15);
        o.sayHi();//输出的是什么?为什么?
        o.sayHello("李四");//输出的是什么?为什么?
    }
}
class Aoo{//超类
    String name;
    Aoo(){}
    Aoo(String name){
        this.name = name;
        System.out.println("超类");
    }
    void sayHi() {
        System.out.println("Aoo的方法");
    }
    void sayHello(String name){
        System.out.println("大家好我叫"+name);
    }
}
class Boo extends Aoo{//派生类
    int age;
    Boo(){}
    Boo(String name,int age){
        super(name);
        this.age = age;
        System.out.println("派生类");
    }
    void sayHi() {
        System.out.println("Boo的方法");
    }
    void sayHello(String name){
        System.out.println("大家好我叫"+name + ",今年"+age+"岁了");
    }
}

1.2 静态static 
应用知识点: 
静态变量属于类实例变量属于对象 
1.2.1 第一题 
创建一个 Student 类 
  变量 money (钱) ,每个学生出门前,兜里揣了100元,(默认值 100 块)变量 water (饮用水),教室门前有一桶水,默认值 10000 ml创建一个方法 buy,方法目的是买水,每个人花 5 元,买500ml 水main 方法中,创建3个学生对象,分别调用买水方法,观察最终每个学生剩多少钱,水剩多少思考:变量应该是什么变量分析并画出内存结构图  
2. 答案 
2.1 
 未完待续… 
2.2 
2.2.1 
1. 第一种写法 
public class Student {

 

    public double money = 100; // 钱是每个人自己独有的
    public static int water = 10000; // 饮水机里的水是班级里所有学生所共有的

    public static void main(String[] args) {
        Student s1 = new Student();
        s1.buy();
        Student s2 = new Student();
        s2.buy();
        Student s3 = new Student();
        s3.buy();
    }

    void buy() {
        money-=5;
        water-=500;
        System.out.println("money = " + money +" , water = " + water);
    }
}
2. 第二种写法 
public class Student {

    public double money = 100;
    public static int water = 10000;

    public static void main(String[] args) {
        Student[] students = new Student[3];
        for (int i = 0; i < students.length; i++) {
            students[i] = new Student();
            students[i].buy();
        }
    }

    void buy() {
        money-=5;
        water-=500;
        System.out.println("money = " + money +" , water = " + water);
    }
}在这里插入图片描述

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值