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

Java新手小白入门篇 Java面向对象(知识点体系汇总)

  • 面向对象知识链接汇总,知识点体系(思维导图)

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

  • Java面向对象(第一天)类,对象,方法的重载,练习题

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

  • Java面向对象(第二天)构造方法,this关键字,内存结构初识,null,NullPointerException,引用类型数组(上),拓展,练习题

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

  • Java面向对象(第三天)引用类型数组(下),继承,super,向上造型(上),拓展,练习题

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

  • Java面向对象(第四天)向上造型(下),重写,访问控制修饰符,static关键字,拓展,练习题

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

  • Java面向对象(第五天)final,static final,abstract关键字(抽象方法,抽象类)

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

  • Java面向对象(第六天)成员内部类(不经常使用),匿名内部类(经常使用)

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

  • Java面向对象(第五天)接口,拓展(类与接口的关系,抽象类与接口的区别),练习题

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

  • Java面向对象(第八天)多态(对象的多态,行为的多态),拓展(面向对象)

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

  • Java面向对象(第九天)简单的内存结构,面向对象三大特征

  • Java新手小白入门篇系列持续更新中…


一、向上造型(下)

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. 定义

重写(覆盖):父子类中,子类方法与父类方法的名称相同,参数列表也相同我们称之为方法的重写
方法的签名 = 方法名称 + 参数列表
我们又称:父子类中,子类与父类方法的签名相同的方法叫方法的重写
当父类提供的方法不能满足你的业务需求时,需要重写

2. 案例

在这里插入图片描述

三、访问控制修饰符

访问范围privatedefault(默认的)protectedpublic
本类中可访问可访问可访问可访问
同包中的其它类不可访问可访问可访问可访问
不同包中的子类不可访问不可访问可访问可访问
不同包中的非子类不可访问不可访问不可访问可访问
  • 类的访问控制权限只能是 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 概念
  1. 重载(overload)
    • 发生在同一个类中,方法名相同,参数列表不同,方法体不同
    • 与返回值类型无关
    • 编译期绑定
  2. 重写(override)
    • 发生在父子类中,方法名称相同,参数列表相同(方法名称+参数列表=方法的签名)方法体不同
    • 重写遵循两同两小一大
      • 1)两同:方法名相同,参数列表相同(方法的签名)
      • 2)两小:(返回值类型、异常、访问权限)
        • A. 子类方法的返回值小于等于父类方法的返回值
          • a. void/基本类型返回值必须相同
          • b. 引用类型的返回值小于等于父类的返回值
        • B. 子类方法抛出的异常小于或等于超类的方法抛出的异常
      • 3)一大:子类方法的访问权限大于或等于父类方法的
    • 运行期绑定
1.2 案例

重写:

  • 两小

    • 子类方法的返回值小于等于父类方法的返回值
      • void/基本类型返回值必须相同

        • void

          class Aoo{//超类
          	void sayHi() {}	
          }
          class Boo extends Aoo{//派生类
          	void sayHi() {}
          }
          
        • 基本类型

          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;}//不是重写
          }
          
      • 引用类型的返回值小于等于父类的返回值

        • 小于指的是父类方法类型的子类,或者子类的子类,等于是指和父类方法类型相同

          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.局部变量

在这里插入图片描述

  1. 成员变量

    • 实例变量
      • 没有static修饰,属于对象的,存储在堆中,有几个对象就有几份(new),通过对象名点来访问
    • 静态变量(类变量)
      • 由static修饰,属于类的,存储在方法区中,只有一份,常常通过类名点来访问
        我们常常说实例变量属于对象,静态变量属于类。
        在这里插入图片描述
  2. 局部变量

    • 形参:方法签名中定义的变量
    • 代码块(语句块):{ }

六、练习题

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、付费专栏及课程。

余额充值