Day 11笔记-多态-抽象-静态-最终

JavaSE基础

一、多态

1.1 概述

  • 生活中的多态
    • 事物在人脑中的主观印象
    • 狗–》动物
  • 程序中的多态
    • 声明的变量类型是父类类型
    • 创建的对象类型是子类类型
    • 父类变量存储的是子类对象的地址
    • 父类引用指向子类对象

1.2 多态的特点

  • 多态方式创建对象只能使用声明的类型中的属性和方法
    • 方法存在重写
    • 属性不存在覆盖【访问的属性依旧是父类中的内容】
  • 如果方法被子类重写,执行的是重写之后的方法

1.3 动态使用–父类声明为方法形参

  • 能接收父类和子类类型的对象
  • Worker父类
    • Cook
    • Driver
    • Programmer
  • 编写方法,展示这个工人工作的方式
Worker
package com.javastudy.work01;

public class Work {
	 public void work(){
		System.out.println("工作");
	}
}

Cook
package com.javastudy.work01;

public class Cook extends Work{
	@Override
	public void work() {
		System.out.println("厨师工作是做饭");
	}
}

Driver
package com.javastudy.work01;

public class Driver extends Work{
	@Override
	public void work() {
		System.out.println("司机的工作是开车");
	}
}

Programmer
package com.javastudy.work01;

public class Programmer extends Work{
	@Override
	public void work() {
		System.out.println("程序员的工作是敲代码");
	}
}

Main
package com.javastudy.work01;

public class Main {
	public static void main(String[] args) {
		Work work = new Work();
		work(work);
		
		Cook cook = new Cook();
		work(cook);
		
		Driver driver = new Driver();
		work(driver);
	}
	public static void work(Work work) {
		work.work();
	}
}

1.4 多态使用-声明为方法返回值类型

  • 能返回父类和子类类型的对象
  • 编写方法点餐,返回下面类型的对象之一
  • Food父类
    • 东坡肉
    • 西湖醋鱼
    • 扬州炒饭
    • 鸭血粉丝汤
  • 展示食物的信息
Food
package com.javastudy.work02;

public class Food {
	public void eat() {
		System.out.println("吃饭");
	}


DongPoPork
package com.javastudy.work02;

public class DongPoPork extends Food{
	@Override
	public void eat() {
		System.out.println("东坡肉");
	}
}

WestLakeFish
package com.javastudy.work02;

public class WestLakeFish extends Food{
	@Override
	public void eat() {
		System.out.println("西湖醋鱼");
	}
}

YangzhouFriedRice
package com.javastudy.work02;

public class YangzhouFriedRice extends Food {
	@Override
	public void eat() {
		System.out.println("扬州炒饭");
	}
}

DuckBloodSoup
package com.javastudy.work02;

public class DuckBloodSoup extends Food {
  @Override
  public void eat() {
	System.out.println("鸭血粉丝汤");
}
}

Main
package com.javastudy.work02;

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {

		System.out.println("请选择您想要的食物【1==东坡肉,2==西湖醋鱼,3==扬州炒饭,4==鸭血粉丝汤】:");

		// 提示输入并获取车子型号
		Scanner sc = new Scanner(System.in);
		int order = sc.nextInt();
		
		// 调用方法获取对象
		Food food = orderFood(order);
		
		food.eat();
	}
	

	public static Food orderFood(int order) {
		Food food = null;
		switch (order) {
			case 1:
				food = new DongPoPork();
				break;
			case 2:
				food = new WestLakeFish();
				break;
			case 3:
				food = new YangzhouFriedRice();
				break;
			case 4:
				food = new DuckBloodSoup();
				break;
	
			default:
				food = new Food();
				break;
		}
		
		return food;
	}
}

1.5 类型转换

向上转型
  • 声明的类型是父类,实际引用指向【保存对象的地址】的对象是子类
  • 天生安全,多态的核心使用方式
向下转型
  • 声明的类型是子类,引用执行父类
  • 有风险,可能造成类型转换异常
Animal
package com.javastudy.work03;

public class Animal {
	void sleep() {System.out.println("睡觉");}
}

Cat
package com.javastudy.work03;

public class Cat extends Animal{
  @Override
void sleep() {
	// TODO Auto-generated method stub
	System.out.println("猫需要休息");
}
}

Dog
package com.javastudy.work03;

public class Dog extends Animal{
	@Override
	void sleep() {
		System.out.println("狗需要休息");
	}
}

Demo01
package com.javastudy.work03;

public class Main {
 public static void main(String[] args) {
	 /**
		 *	父类
		 *		Animal
		 *	子类
		 *		Dog
		 *		Cat
		 */
		
		// 正常创建对象:声明的类型和实际创建的类型是相同的
		Animal a = new Animal();
		
		// 动态方式创建对象:声明的类型是父类,实际创建对象是子类类型
		// 向上转型
		Animal aa = new Dog();
		aa.sleep();
		
		// 向下转型
		Dog dog = (Dog) aa;
		dog.sleep();
		System.out.println(dog.getClass());
		// 向下转型,声明类型和对象类型不匹配,报错:java.lang.ClassCastException
		//Cat cat = (Cat) aa;
		//System.out.println(cat.getClass());
		// 判定对象是否属于指定类型
		System.out.println(aa instanceof Animal);
		System.out.println(aa instanceof Dog);
		System.out.println(aa instanceof Cat);
 }
}

二、抽象

2.1 概述

  • 使用abstract修饰的内容成为抽象
    • 抽象类
    • 抽象方法

2.2 抽象类

 *	在Java中有些累不适合直接创建对象
 *		创建的对象不能准确表示现实中的任何对象
 *		应该限制其创建对象
 *	使用abstract修饰类,这样的类成为抽象类,不能直接创建对象
抽象类Human
package com.javastudy.work04;

public class Animal {
	/**
	 *	抽象类Animal
	 *		创建的对象不够具体,限制创建对象,动物只是宽泛的概念,没有具体的实体
	 */
		String name;
		int age;
		String sex;		
		public void eat() {}		
		public void sleep() {}
}

抽象类的作用
  • 当前其他类的父类
    • 提供多个子类中共有的属性和方法
  • 在创建对象时候声明为父类类型
    • 更自然的使用多态
package com.javastudy.work04;

public class Lion extends Animal{}
package com.javastudy.work04;

public class Main {
 public static void main(String[] args) {
	 /**
		 *	在Java中有些累不适合直接创建对象
		 *		创建的对象不能准确表示现实中的任何对象
		 *		应该限制其创建对象
		 *	使用abstract修饰类,这样的类成为抽象类,不能直接创建对象
		 */
		// 声明的类型父类,创建的对象类型是子类
		Animal a01 = new Leopard();
		Animal a02 = new Lion();	
 }
}

2.3 抽象方法

  • 有些方法在父类中定义,方法的实现部分多余
    • 动物类类中吃饭的方法:动物都会吃饭,吃饭的方式多数不同,子类一般需要重写这些方法
    • 可以把方法的声明部分保留,实现部分删除,定义成为抽象方法
  • 如果父类中存在抽象方法
    • 子类重写所有抽象方法
    • 或者子类也是抽象类
Car
package com.javastudy.work05;

public abstract class Car {
	public abstract void run();	
}

Gasoline
package com.javastudy.work05;

public class Gasoline extends Car{

	@Override
	public void run() {
		System.out.println("油车依靠油驱动");
		
	}

}

Electric
package com.javastudy.work05;

public class Electric extends Car{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("电车用电来驱动");
	}

}

Main
package com.javastudy.work05;

public class Main {
	public static void main(String[] args) {
		Car car= new Gasoline();
		car.run();
	}

}

三、static

3.1 概述

  • 被static修饰的内容成为静态的内容
    • static修饰的变量成为静态属性,也称为类属性
    • static修饰的方法成为静态方法,也称为类方法
    • 静态的数据随着类的加载而加载,无需等待对象创建即可使用【使用类名直接调用】

3.2 静态变量

  • 使用static修饰的变量成为静态变量
  • 此类创建的所有对象共用一个静态变量
  • 如果在任何位置修改了静态变量,其他所有对象都会收到影响
Country
package com.javastudy.work05;

public class Country {
	int year;
	static String name = "M国";
	
	public void show() {
		// TODO Auto-generated method stub
		System.out.println(name +"建立在"+year);
	}
}

Main02
package com.javastudy.work05;

public class Main02 {
	public static void main(String[] args) {
		// 静态属性 == 类属性,跟随类一起加载进入内存,无序创建对象即可使用
		System.out.println(Country.name);
				
		// 创建对象
		Country  c1= new Country();
		c1.year = 18;
		c1.show();
				
		Country  c2= new Country();
		c2.year = 23;
		c2.show();
				
		c1.show();
		c2.show();
				
		System.out.println("--------------------------");
				
		// k02.capital = "首尔";
		// 静态的数据存储在方法区,和类对象放在一起,是类变量,推荐使用类名直接调用
		Country.name = "首尔";
		c1.show();
		c2.show();
	}

}

3.3 课堂案例

  • 统计一个类在运行期间创建了多少对象
public class User {
	String name;
	// 静态的属性,用来记录创建对象的次数
	private static int count = 0;
	
	public User() {
		count++;
	}
	
	public User(String name) {
		this.name = name;
		count++;
	}
	
	public static int getCount() {
		return count;
	}
	
}
public class Demo02 {
	public static void main(String[] args) {
		/**
		 * 	User
		 *		统计一个类在运行期间创建了多少对象
		 */
		
		for (int i = 0; i < 150; i++) {
			new User();
		}
		System.out.println(User.getCount());
	}
}

3.4 静态方法

  • 使用static修饰的方法成为静态方法【类方法】
  • 可以使用类名直接调用【不用创建对象即可调用】
  • 静态方法中只能访问静态数据,不能访问非静态数据、不能访问this、super
package com.javastudy.work05;

public class User {
	public static void main(String[] args) {
		User user = new User();
		user.show();
	}

	String name = "张三";
	// 静态的属性,用来记录创建对象的次数
	private static int count = 0;
	
	public User() {
		count++;
	}
	
	public User(String name) {
		this.name = name;
		count++;
	}
	
	public static int getCount() {
		return count;
	}
	
	// 实例方法
	public void show() {
		// 实例方法访问实例属性和静态属性
		System.out.println(name);
		System.out.println(count);
		
		// 实例方法调用实例方法和静态方法
		showStatic();
		System.out.println(this);
	}
	
	// 静态方法
	public static void showStatic() {
		// 实例属性需要先创建对象才能使用,静态方法中不能访问实例遍历【静态早于实例】
		// System.out.println(name);
		System.out.println(count);
		
		// 静态的方法不能调用非静态的方法
		// show();
		// System.out.println(this);
		// System.out.println(super);
	}
}

四、代码块

4.1 概述

  • 代码块就是使用{}包裹的一块代码
  • 没有名字,自动执行
  • 根据位置和修饰符可以分为:
    • 局部代码块
    • 动态代码块【构造代码块、成员代码块】
    • 静态代码块
    • 同步代码块【多线程部分讲解】

4.2 局部代码块

  • 定义在方法中的代码块称为局部代码块
  • 自动执行,无需【无法】手动调用
public class Demo01 {
	public static void main(String[] args) {
		// 局部变量
		int num = 100;
		System.out.println("Hello001");
		System.out.println("Hello002");
		{
			System.out.println("我是局部代码块");
			System.out.println(num);
			
			int ii = 200;
			System.out.println(ii);
		}
		System.out.println("Hello003");
		System.out.println("Hello004");
		// System.out.println(ii);
	}	
}

4.3 动态代码块

  • 动态代码块也称为构造代码块
  • 位置和构造器同一级:类中方法外
  • 构造代码块每一次创建对象都自动执行一次,执行时间早于构造器
  • 可以把构造方法中共同的内容抽取出来放在构造代码块中执行

4.4 静态代码块

  • 使用static修饰的代码块成为静态代码块
  • 位置和构造器同一级:类中方法外
  • 静态代码块在程序运行过程中最多执行一次
  • 适用于类的初始化,一般加载驱动使用
public class User {
	String name;
	static int count = 0;
	
	static {
		System.out.println("静态代码块");
	}
	
	{
		System.out.println("构造代码块");
		count++;
	}

	public User() {
		System.out.println("无参数构造器");
	}

	public User(String name) {
		this.name = name;
		System.out.println("有参数构造器");
	}
	
	public static int getCount() {
		return count;
	}
}

4.5 同步代码块

  • 多线程线程安全问题时候讲解
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值