Java基础 - 面向对象(5) : final关键字、多态、抽象

1. final 关键字特点

  • final可以修饰类,该类不能被继承。
  • final可以修饰方法,该方法不能被重写。
  • final可以修饰变量,该变量不能被重新赋值。因为这个变量其实是常量。
  • 常量:
    A. 字面值常量 : “hello” , 10 , true
    B. 自定义常量 : final int x = 10 ;

2. final 修饰局部变量的问题

  • 基本类型:基本类型的值不能发生改变。
  • 引用类型:引用类型的地址值不能发生改变。但是,该对象的堆内存的值是可以改变的。
class Student {
	int age = 10;
}

class FinalTest {
	public static void main(String[] args) {
		
		int x = 10;
		x = 100;
		System.out.println(x);
		final int y = 10;
		
//		y = 100; 此行为错误,不能改变final关键字修饰的基本变量的值。
		System.out.println(y);
		System.out.println("--------------");
		
		
		Student s = new Student();
		System.out.println(s.age);
		s.age = 100;
		System.out.println(s.age);
		System.out.println("--------------");
		
		final Student ss = new Student();
		System.out.println(ss.age);
		ss.age = 100;
		System.out.println(ss.age);
		
		
//		ss = new Student();  此行为错误,因为改变了final引用类型的地址值。
	}
}

3. final 修饰变量的初始化时机

  • a. 只能初始化一次。

  • b. 常见的给值 :

    定义的时候。(推荐)
    构造方法中。

4. 多态的概述和前提条件

  • 多态:同一个对象(事物),在不同时刻体现出来的不同状态。

  • 多态的前提:

    A. 有继承或者实现关系。
    B. 有方法重写。
    C. 有父类或者父接口引用指向子类对象。

5. 多态中的成员访问特点

  • A. 成员变量 : 编译看左边,运行看左边
  • B. 构造方法 : 子类的构造都会默认访问父类构造
  • C. 成员方法 : 编译看左边,运行看右边
  • D. 静态方法 : 编译看左边,运行看左边
  • 为什么 ? 因为成员方法有重写。
class Fu {
	public int num = 100;

	public void show() {
		System.out.println("show Fu");
	}
	
	public static void function() {
		System.out.println("function Fu");
	}
}

class Zi extends Fu {
	public int num = 1000;
	public int num2 = 200;

	public void show() {
		System.out.println("show Zi");
	}
	
	public void method() {
		System.out.println("method zi");
	}
	
	public static void function() {
		System.out.println("function Zi");
	}
}

class DuoTaiDemo {
	public static void main(String[] args) {
		
		Fu f = new Zi();
		System.out.println(f.num);
		
		//System.out.println(f.num2);
		
		f.show();
		
		//f.method();
		f.function();
	}
}

上述代码的运行结果为:

100
show Zi
function Fu

6. 多态中向上转型和向下转型

  • 向上转型:Fu f = new Zi( );
  • 向下转型:Zi z = (Zi)f; // 要求该f必须是能够转换为Zi的。
class Fu {
	public void show() {
		System.out.println("show fu");
	}
}

class Zi extends Fu {
	public void show() {
		System.out.println("show zi");
	}
	
	public void method() {
		System.out.println("method zi");
	}

}

class DuoTaiDemo4 {
	public static void main(String[] args) {
		
		Fu f = new Zi();
		f.show();
		//f.method();
		
		
		//Zi z = new Zi();
		//z.show();
		//z.method();
		
	
		Zi z = (Zi)f;
		z.show();
		z.method();
	}
}

上述代码的运行结果为:

show zi
show zi
method zi

7. 猫狗案例多态版

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

class Dog extends Animal {
	public void eat() {
		System.out.println("狗吃肉");
	}
	
	public void lookDoor() {
		System.out.println("狗看门");
	}
}

class Cat extends Animal {
	public void eat() {
		System.out.println("猫吃鱼");
	}
	
	public void playGame() {
		System.out.println("猫捉迷藏");
	}
}

class DuoTaiTest {
	public static void main(String[] args) {
		//定义为狗
		Animal a = new Dog();
		a.eat();
		System.out.println("--------------");
		//还原成狗
		Dog d = (Dog)a;
		d.eat();
		d.lookDoor();
		System.out.println("--------------");
		//变成猫
		a = new Cat();
		a.eat();
		System.out.println("--------------");
		//还原成猫
		Cat c = (Cat)a;
		c.eat();
		c.playGame();
		System.out.println("--------------");
		
		//演示错误案例
		//Dog dd = new Animal();
		//Dog ddd = new Cat();
		//ClassCastException
//		Dog dd = (Dog)a;
	}
}	

上述代码运行结果为:

狗吃肉
--------------
狗吃肉
狗看门
--------------
猫吃鱼
--------------
猫吃鱼
猫捉迷藏
--------------

8. 南北方人多态案例

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

class SouthPerson extends Person {
//	public void eat() {
//		System.out.println("炒菜,吃米饭");
//	}
	
	public void jingShang() {
		System.out.println("经商");
	}
}

class NorthPerson extends Person {
	public void eat() {
		System.out.println("炖菜,吃煎饼果子");
	}
	
	public void yanJiu() {
		System.out.println("研究");
	}
}

class DuoTaiTest2 {
	public static void main(String[] args) {
		
		Person p = new SouthPerson();
		p.eat();
		System.out.println("-------------");
		SouthPerson sp = (SouthPerson)p;
		sp.eat();
		sp.jingShang();
		System.out.println("-------------");
		
		
		p = new NorthPerson();
		p.eat();
		System.out.println("-------------");
		NorthPerson np = (NorthPerson)p;
		np.eat();
		np.yanJiu();
	}
}

上述代码的运行结果为:

吃饭
-------------
吃饭
经商
-------------
炖菜,吃煎饼果子
-------------
炖菜,吃煎饼果子
研究

9. 多态练习题看程序写结果

  • A. 多态的成员访问特点:编译看左边,运行看右边。

  • B. 继承的时候:

    子类中有和父类中一样的方法,叫重写。
    子类中没有父类中出现过的方法,直接继承过来。

class A {
	public void show() {
		show2();
	}
	public void show2() {
		System.out.println("我");
	}
}
class B extends A {
	/*
	public void show() {  因为B类没有show()方法,所以直接继承父类A的show()方法。
		show2();
	}
	*/

	public void show2() {
		System.out.println("爱");
	}
}
class C extends B {
	public void show() {
		super.show();
	}
	public void show2() {
		System.out.println("你");
	}
}
public class DuoTaiTest4 {
	public static void main(String[] args) {
		A a = new B();
		a.show();
		
		B b = new C();
		b.show();
	}
}

上述程序的运行结果为:

爱
你

10. 抽象类的概念和特点

  • 概念:

    把多个共性的东西提取到一个类中,这是继承的做法。

    但是呢,这多个共性的东西,在有些时候,方法声明一样,但是方法体不一样。

    也就是说,方法声明一样,但是每个具体的对象在具体实现的时候内容不一样。比如猫和狗的吃饭功能都继承自动物类,但是猫吃鱼,狗啃骨头。

    所以,我们在定义这些共性的方法的时候,就不能给出具体的方法体。

    而一个没有具体的方法体的方法是抽象的方法。

    在一个类中如果有抽象方法,该类必须定义为抽象类。

  • 特点:

  • A. 抽象类和抽象方法必须用关键字abstract修饰

  • B. 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类

  • C. 抽象类不能实例化

  • D. 抽象类的子类

    a. 是一个抽象类。
    b. 是一个具体类。这个类必须重写抽象类中的所有抽象方法。

11. 抽象类的成员特点

  • A. 成员变量 : 有变量,有常量

  • B. 构造方法 : 有构造方法

  • C. 成员方法 : 有抽象,有非抽象

  • D. 成员方法的特性:

    a. 抽象方法 强制要求子类做的事情。若父类中有抽象方法,则子类中必须写一模一样的方法。
    b. 非抽象方法 子类继承的事情,提高代码复用性。

abstract class Animal {
	public int num = 10;
	public final int num2 = 20;

	public Animal() {}
	
	public Animal(String name,int age){}
	
	public abstract void show();  // 继承它的子类中必须写public void show()方法
	
	public void method() {
		System.out.println("method");
	}
}

 class Dog extends Animal {
	public void show() {
		System.out.println("show Dog");
	}
}

class AbstractDemo2 {
	public static void main(String[] args) {
		
		Animal a = new Dog();
		a.num = 100;
		System.out.println(a.num);
		//a.num2 = 200; 此处为错误,因为num2 关键字“final” 相当于常量
		System.out.println(a.num2);
		System.out.println("--------------");
		a.show();
		a.method();
	}
}

12. 抽象类练习员工案例

abstract class Employee {
	
	private String name;
	private String id;
	private int salary;
	
	public Employee() {}
	
	public Employee(String name,String id,int salary) {
		this.name = name;
		this.id = id;
		this.salary = salary;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getId() {
		return id;
	}
	
	public void setId(String id) {
		this.id = id;
	}
	
	public int getSalary() {
		return salary;
	}
	
	public void setSalary(int salary) {
		this.salary = salary;
	}
	
	
	public abstract void work();
}


class Programmer extends Employee {
	public Programmer(){}
	
	public Programmer(String name,String id,int salary) {
		super(name,id,salary);
	}
	
	public void work() {
		System.out.println("完成经理部署的任务");
	}
}


class Manager extends Employee {
	
	private int money; 

	public Manager(){}
	
	public Manager(String name,String id,int salary,int money) {
		super(name,id,salary);
		this.money = money;
	}
	
	public void work() {
		System.out.println("安排普通成员的工作");
	}
	
	public int getMoney() {
		return money;
	}
	
	public void setMoney(int money) {
		this.money = money;
	}
}

class AbstractTest4 {
	public static void main(String[] args) {
		
		Employee emp = new Programmer();
		emp.setName("徐康健");
		emp.setId("xkj91354");
		emp.setSalary(8000);
		System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
		emp.work();
		System.out.println("-------------");
		emp = new Programmer("高晗","hanxue899",18000);
		System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
		emp.work();
		System.out.println("-------------");
		
		
//		emp = new Manager();
//		emp.setName("带带大师兄");
//		emp.setId("cxk002");
//		emp.setSalary(8000);
//		emp.setMoney(2000);
		
		
		Manager m = new Manager();
		m.setName("杨腾宇");
		m.setId("yty6352184");
		m.setSalary(80000);
		m.setMoney(20000);
		System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
		m.work();
		System.out.println("-------------");
		
		// 用构造方法赋值
		m = new Manager("杨博雯","yty5537238",81000,24000);
		System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
		m.work();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值