day06_oop

1 继承内存图

在这里插入图片描述

2 继承练习

2.1

1 定义一个形状类:shape 有方法:getZC和getMJ  三个子类:Circle和Square和Rect 定义必要的属性:重写父类的方法
package day07_oop;

public class LianXi01 {
       public static void main(String[] args) {
    	   Circle01 c1=new Circle01();
    	   c1.setR(1);
    	   System.out.println("周长="+c1.getZC()+",面积="+c1.getMJ());
	    }
}
//1 定义一个形状类:shape 有方法:getZC和getMJ  三个子类:Circle和Square和Rect 定义必要的属性:重写父类的方法
abstract class Shape01{
	abstract double getZC();//1 满足语法不报错 2 没有可能被调用 此类不具体   
	abstract double getMJ() ;//1 满足语法不报错 2 没有可能被调用 此类不具体
}
class Circle01 extends Shape01{
	  //特有成员变量
	   private double r;
	   public static final double PI=3.1415926;//PI的值是固定的 加修饰符final  所有圆的PI值是一样的 加修饰符static
	   //所有的属性私有化
	   public double getR() {return r;}
	   public void setR(double r) {this.r=r;}
	   double getZC() {//根据自己的需求 重写父类的方法
			return 2*PI*r;
		}
		double getMJ() {//根据自己的需求 重写父类的方法
			return PI*r*r;  
		}
}
class Square extends Shape01{
	 private double bianChang;

	public double getBianChang() {
		return bianChang;
	}
	public void setBianChang(double bianChang) {
		this.bianChang = bianChang;
	}
	double getZC() {//根据自己的需求 重写父类的方法
			return 4*bianChang;
	}
	double getMJ() {//根据自己的需求 重写父类的方法
			return bianChang*bianChang; 
	}
}
class Rect extends Shape01{
	private double chang;
	private double kuan;
	public double getChang() {
		return chang;
	}
	public void setChang(double chang) {
		this.chang = chang;
	}
	public double getKuan() {
		return kuan;
	}
	public void setKuan(double kuan) {
		this.kuan = kuan;
	}
	double getZC() {//根据自己的需求 重写父类的方法
			return 2*(chang+kuan);
	}
	double getMJ() {//根据自己的需求 重写父类的方法
			return chang*kuan; 
	}
}

2.2

2 定义一个lamp台灯类:有方法on和off  定义一个bulb类有方法faLiang   灯泡有两种:红灯和绿灯 怎么设计 让台灯可以开on启指定灯泡的 faLiang
package day07_oop;

public class LianXi02 {
    
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Lamp l=new Lamp();
		RedBulb01 rr=new RedBulb01();
		rr.setName("红灯1号");
		l.r=rr;
		l.on();
		l.off();

	}

}
//2 定义一个lamp台灯类:有方法on和off  定义一个bulb类有方法faLiang   灯泡有两种:红灯和绿灯 怎么设计 让台灯可以开on启指定灯泡的 faLiang
class Lamp{
	RedBulb01 r;//灯泡是台灯的一部分 把灯泡定义为台灯属性
	GreenBulb01 g;//灯泡是台灯的一部分 把灯泡定义为台灯属性
	void on() {
		System.out.println("台灯启动!");
		if(r!=null)r.faLiang();
		if(g!=null)g.faLiang();
	}
	void off() {
		System.out.println("台灯关闭!");
	}
}
class RedBulb01 extends Bulb{
	void faLiang() {//根据需求重写父类的方法
		System.out.println("我的灯泡:"+getName()+",我在发光:红红红红红红红红红红红红");
	}
}
class GreenBulb01 extends Bulb{
	void faLiang() {//根据需求重写父类的方法
		System.out.println("我的灯泡:"+getName()+",我在发光:绿绿绿绿绿绿绿绿绿绿绿绿绿");
	}
}
//提取共同成员 形成父类
abstract class Bulb{
	private String name;
	abstract void faLiang();
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

2.3

1:(封装、继承、super)某公司的雇员分为以下若干类:
Employee:这是所有员工总的父类,属性:员工的姓名,员工的生日月份。方法:
getSalary(intmonth) 根据参数月份来确定工资,如果该月员工过生日,则公司
会额外奖励100 元。
SalariedEmployee:Employee 的子类,拿固定工资的员工。属性:月薪
HourlyEmployee:Employee 的子类,按小时拿工资的员工,每月工作超出160 小
时的部分按照1.5 倍工资发放。属性:每小时的工资、每月工作的小时数
SalesEmployee:Employee 的子类,销售人员,工资由月销售额和提成率决定。
属性:月销售额、提成率
BasePlusSalesEmployee:SalesEmployee 的子类,有固定底薪的销售人员,工
资由底薪加上销售提成部分。属性:底薪。
根 据 要 求 创 建 SalariedEmployee 、 HourlyEmployees 、 SaleEmployee 和
BasePlusSalesEmployee
四个类的对象各一个,并计算某个月这四个对象的工资。
注意:要求把每个类都做成完全封装,不允许非私有化属性。
abstract class Employee{
	String name;
	int brithdayMonth;
	double getSalary(int month) {
		//最终的结果:被子类重写   
		//存在的意义:为子类的方法定义方法声明!
		//没有被调用的可能
		return brithdayMonth==month?100:0;
	}
}
class SalariedEmployee extends Employee{
	double monthSalary;
	double getSalary(int month) {//根据自己的需求重写父类的方法
		//return monthSalary+(brithdayMonth==month?100:0);
		return monthSalary+super.getSalary(month);
	}
}
class SalesEmployee extends Employee{
	double tcl;
	double monthSale;
	double getSalary(int month) {//根据自己的需求重写父类的方法
		//return monthSale*tcl+(brithdayMonth==month?100:0);
		return monthSale*tcl+super.getSalary(month);
	}
}
class HourlyEmployee extends Employee{
	double hourSalary;
	double hours;
	double getSalary(int month) {//根据自己的需求重写父类的方法
		double salary=hourSalary*hours+(hours>160?(hours-160)*hourSalary*0.5:0);
		//return salary+(brithdayMonth==month?100:0);
		return salary+super.getSalary(month);
	}
}
class BasePlusSalesEmployee extends SalesEmployee{
	double baseSalary;
	double getSalary(int month) {//根据自己的需求重写父类的方法
		//return baseSalary+monthSale*tcl+(brithdayMonth==month?100:0);
		return baseSalary+super.getSalary(month);
	}
}

3 abstract

public class Demo01Abstract {
	/*abstract:抽象的 修饰符 修饰类和方法
	 *概念:抽象的:::不具体 模糊 笼统::::信息不完全 无法在现实中找到对应的实例
	 *特点:1 抽象类可以定义引用 但不能创建对象
	 *、        2 抽象方法不能有方法体
	 *     3 有抽象方法的类必须是抽象类::但是抽象类可以没有抽象方法
	 *     4 抽象类的子类 如果不重写父类的所有抽象方法 此子类还是抽象类
	 *     5 抽象类有构造方法:抽象类的构造方法不是用于创建本类对象 而是在创建子类对象时
	 *           通过子类构造方法来调用抽象父类的构造方法 把父类中定义的实例成员 加载进子类对象内存
	 *       简单说:抽象类的构造方法是为创建子类对象服务的
	 *     
	 * 思考:声明情况下 把一个类定义为抽象类::
	 *      1 含有抽象方法的类
	 *      2 要求类不能创建对象    :::信息不完整
	 *      
	 * 练习题中:那些类可以定义为抽象类:     
	 * */
	public static void main(String[] args) {
		Demo1 d1;
		//d1=new Demo();//Cannot instantiate the type Demo
		//d1.hehe();
	}
}
abstract class Demo1{
	int a=1;
	void hehe() {}
	Demo1(){}
}
abstract class Demo2{  //2 The type Demo2 must be an abstract class to define abstract methods
	int a=1;
	void hehe() {}
	abstract void hai1();//1:Abstract methods do not specify a body 抽象方法不能有方法体
	abstract void hai2();
}
//抽象类的子类 如果不重写父类的所有抽象方法 此子类还是抽象类
abstract class Demo2Zi1 extends Demo2{
	void hai1() {}//重写父类的抽象方法
	//void hai2() {}
}
class Demo2Zi2 extends Demo2{
	void hai1() {}//重写父类的抽象方法
	void hai2() {}
} 

4 多态

4.1 什么是多态

父类引用指向子类对象

4.2 多态的对象有什么特点

多态对象的特点:除了重写的方法 其他和父类对象完全相同
package day07_oop;

public class Demo02DuoTai01 {
   public static void main(String[] args) {
	      //创建父类对象
	       Fu02 fu=new Fu02();
	       //创建子类对象
	       Zi02 zi=new Zi02();
	       
	       //多态对象
	       //1 什么是多态:
	       // 父类引用指向子类对象
	       // 等号左边是父类类型的引用 等号右边是子类类型的对象
	       // 把子类对象伪装成父类类型
	       // 被定义了父类类型引用的对象---多态对象
	       Fu02 fuzi=new Zi02();
	       
	       //2 多态对象的特点:除了重写的方法 其他和父类对象完全相同
	       // 多态的前提:继承  重写  让父类引用指向子类对象(步骤:::向上转型)
	       System.out.println(fuzi.a+"::"+fuzi.b);//重新调用的成员变量 显示的是父类的
	       //System.out.println(fuzi.c);//不能调用子类特有的成员变量
	       fuzi.hehe();//重写的方法调用的是子类中定义的
	       fuzi.haha();
	       //fuzi.hai();//不能调用子类特有的成员方法
	       
	       
   }
}
class Fu02{
	int a=11;
	int b=12;
	void hehe() {
		System.out.println("fu hehe");
	}
	void haha() {
		System.out.println("fu haha");
	}
}
class Zi02 extends Fu02{
	int a=22;//重新定义
	int c=12;//子类特有
	void hehe() {//重写
		System.out.println("zi 重写  hehe");
	}
	void hai() {//子类特有
		System.out.println("zi  子类特有 hai");
	}
}

4.3 什么时候使用多态

使用场景1

模拟饲养员喂动物
  • 不使用多态
package day07_oop;

public class Demo0311DuoTaiUse {
    public static void main(String[] args) {
		
	}
    //动物园:有动物
    //实现 饲养员拿指定的动物 喂食 和运动
    static void wei(Dog1 d) {
    	d.eat();
    	d.sport();
    }
    static void wei(Cat1 c) {
    	c.eat();
    	c.sport();
    }
}
class Dog1{
	String name;
	Dog1(String name){this.name=name;}
	void eat() {
		System.out.println("狗:"+name+"正在吃骨头!");
	}
	void sport() {
		System.out.println("狗:"+name+"运动:抓老鼠!");
	}
}
class Cat1{
	String name;
	Cat1(String name){this.name=name;}
	void eat() {
		System.out.println("猫:"+name+"正在吃鱼!");
	}
	void sport() {
		System.out.println("猫:"+name+"运动:晒太阳!");
	}
}
class Pig1{
	String name;
	Pig1(String name){this.name=name;}
	void eat() {
		System.out.println("猪:"+name+"正在吃饲料!");
	}
	void sport() {
		System.out.println("猪:"+name+"运动:睡觉!");
	}
}
    //没有多态:
    //缺点: 1 代码复用性差:::需要为每种动物分别定义一个wei方法
    //      2 代码扩展性差:::有新的动物类型 必须添加新的wei方法 修改饲养员类
    //      3 程序各个功能的耦合度高:::如果Dog类报错 static void wei(Dog d)也报错
  • 使用多态
package day07_oop;

public class Demo0312DuoTaiUse {
    public static void main(String[] args) {
    	Animal2 aa=new Dog2("二哈");
    	wei(aa);
    	wei(new Cat2("波斯猫"));//Animal2 a=new Cat2("波斯猫")
	}
    //动物园:有动物
    //实现 饲养员拿指定的动物 喂食 和运动
    static void wei(Animal2 a) {
    	a.eat();
    	a.sport();
    }
    
}
//1 创建父类:提取子类共同的成员 形成父类
abstract class Animal2{
	String name;
	Animal2(String name){this.name=name;}
	abstract void eat();//动物吃什么 不确定:信息不完整!
	abstract void sport();
}
//2 创建类与类的继承关系 
class Dog2 extends Animal2{
	Dog2(String name){super(name);}
	void eat() {// 3 根据子类需求重写父类方法
		System.out.println("狗:"+name+"正在吃骨头!");
	}
	void sport() {//3 根据子类需求重写父类方法
		System.out.println("狗:"+name+"运动:抓老鼠!");
	}
}
class Cat2 extends Animal2{
	Cat2(String name){super(name);}
	void eat() {//3 根据子类需求重写父类方法
		System.out.println("猫:"+name+"正在吃鱼!");
	}
	void sport() {//3 根据子类需求重写父类方法
		System.out.println("猫:"+name+"运动:晒太阳!");
	}
}
 //使用多态:
    //优点: 1 代码复用性强:::所有的Animal2子类对象都可以传递给wei方法
    //      2 代码扩展性强:::有新的动物类型只需要继承Animal2即可 使用wei方法
    //      3 程序各个功能的耦合度低:有助于分工开发  并且程序某块出错 不会影响其他功能
  • 总结
使用场景1:定义方法参数列表时 定义为父类类型 这样就可以传递任意子类类型的对象

使用场景2

台灯安装灯泡
  • 不使用多态
package day07_oop;

public class Demo0321DuoTaiUse {
	//台灯
	public static void main(String[] args) {
		RedBlub01 rr=new RedBlub01("红灯1号");
		Lamp01 l1=new Lamp01();
		l1.r=rr;
		l1.on();
	}
}
class Lamp01{
	RedBlub01 r;
	GreenBlub01 g;
	void on() {
		if(r!=null) {r.faLiang();}
		if(g!=null) {g.faLiang();}
	}
}
class RedBlub01{
	String name;

	public RedBlub01(String name) {
		this.name = name;
	}
	public void faLiang() {
		System.out.println("我是红灯:"+name+"开始发亮:红光");
	}
}
class GreenBlub01{
	String name;

	public GreenBlub01(String name) {
		this.name = name;
	}
	public void faLiang() {
		System.out.println("我是绿灯:"+name+"开始发亮:绿光");
	}
}
//不用多态: 
	//缺点: 1 代码复用性差:Lamp01需要为每种Blub定义引用 来指向不同的Blub对象
	//      2 代码耦合度高:必须所有的Blub都定义完毕 Lamp01才能进行开发 
	//      3 程序扩展性差:当有新的Blub类型 必须更改Lamp 添加此类型的成员变量
  • 使用多态
package day07_oop;

public class Demo0322DuoTaiUse {
	//台灯
	public static void main(String[] args) {
		RedBlub02 rr=new RedBlub02("红灯1号");
		Lamp02 l1=new Lamp02();
		l1.r=rr;//多态
		l1.on();
		GreenBlub02 gg=new GreenBlub02("绿灯2号");
		l1.r=gg;//多态
		l1.on();
	}
	
	
	 //1 定义三个类型:circle square rect  :qiuZC 和qiuMJ方法
	 //     写一个方法:get01(int n) n>0返回一个circle对象  n<0 返回一个square对象  n =0 返回一个rect对象
	 //2 定义一个数组6个元素的数组:装2个circle 2个 square 2个rect
}
class Lamp02{
	Blub02 r;
	void on() {
		if(r!=null) {r.faLiang();}
	}
}
//1 定义父类:抽取子类共同成员
abstract class Blub02{
	String name;
	public Blub02(String name) {
		this.name = name;
	}
	public abstract void faLiang();
}
//2 所有子类继承父类
class RedBlub02  extends Blub02{
	public RedBlub02(String name) {
		super(name);
	}
	public void faLiang() {//3 重写父类的方法
		System.out.println("我是红灯:"+name+"开始发亮:红光");
	}
}
class GreenBlub02  extends Blub02{
	public GreenBlub02(String name) {
		super(name);
	}
	public void faLiang() {//3 重写父类的方法
		System.out.println("我是绿灯:"+name+"开始发亮:绿光");
	}
}
//使用多态: 
	//优点: 1 代码复用性强:Lamp02只需要定义一个父类引用 就能接收所有子类类型的对象
	//      2 代码耦合度低:只要把父类定义完毕:Lamp02和所有的灯泡都可以同步开发
	//      3 程序扩展性强:当有新的Blub类型只需要继承Blub02 就可以被Lamp02使用
  • 总结
使用场景1:定义方法参数列表时 定义为父类类型 这样就可以传递任意子类类型的对象
使用场景2:在定义成员变量时 定义为父类类型 这样就可以赋值任意子类类型的对象

使用场景3

    //1 定义三个类型:circle square rect  :qiuZC 和qiuMJ方法
	 //     写一个方法:get01(int n) n>0返回一个circle对象  n<0 返回一个square对象  n =0 返回一个rect对象
	 //方法的返回值类型:写成circle square rect任何一个都不行  只能写成父类类型
package day07_oop;

public class Demo033DuoTaiUse {
	public static void main(String[] args) {
		Shape02 s=geto1(1) ;
		s.show();
		s=geto1(-1) ;
		s.show();
		s=geto1(0) ;
		s.show();
	}

	public static  Shape02 geto1(int n) {
		if(n>0) { return new Circle02(1);}//多态
		if(n==0) { return new Rect02(3, 2);}//多态
		return new Square02(2);//多态
	}
}
//1 定义类父类:给子类的方法定义规范
abstract class Shape02{
	abstract double qiuZC();
	abstract double qiuMJ();
	abstract void show();
}
//2 创建子类 继承父类
class Circle02 extends Shape02{
	public static final double PI=3.14;
	private double r;
	Circle02(double r) {this.r=r;}
	double qiuZC() {
		return 2*PI*r;
	}
	double qiuMJ() {
		return r*PI*r;
	}
	void show() {
		System.out.println("圆形:半径="+r);
	}
}
class Square02 extends Shape02{
	private double bianChang;
	Square02(double bianChang) {this.bianChang=bianChang;}
	double qiuZC() {
		return 4*bianChang;
	}
	double qiuMJ() {
		return bianChang*bianChang;
	}
	void show() {
		System.out.println("正方形:边长="+bianChang);
	}
}
class Rect02 extends Shape02{
	private double chang,kuan;
	Rect02(double chang,double kuan) {this.chang=chang;this.kuan=kuan;}
	double qiuZC() {
		return 2*(chang+kuan);
	}
	double qiuMJ() {
		return chang*kuan;
	}
	void show() {
		System.out.println("长方形:"+chang+":"+kuan);
	}
}

  • 总结
//使用场景3:定义方法返回值类型时 定义为父类类型 这样就可以返回任意子类类型的对象

使用场景4

//定义三个类型:circle square rect  :qiuZC 和qiuMJ方法
//2 定义一个数组6个元素的数组:装2个circle 2个 square 2个rect
//定义数组必须明确:元素类型+元素个数 元素类型必须定义为父类类型 才能装任意子类类型的对象
package day07_oop;

public class Demo034DuoTaiUse {
	public static void main(String[] args) {
		Shape03[] arr=getArr();
		for (int i = 0; i < arr.length; i++) {
			arr[i].show();
		}
	}
	public static Shape03[]  getArr() {
		Shape03[] arr=new Shape03[6];
		for (int i = 0; i <arr.length; i+=3) {
			arr[i]=new Circle03(i+1);//多态
			arr[i+1]=new Square03(2+i);//多态
			arr[i+2]=new Rect03(i+3, i+2);//多态
		}
		return arr;
	}
}
//1 定义类父类:给子类的方法定义规范
abstract class Shape03{
	abstract double qiuZC();
	abstract double qiuMJ();
	abstract void show();
}
//2 创建子类 继承父类
class Circle03 extends Shape03{
	public static final double PI=3.14;
	private double r;
	Circle03(double r) {this.r=r;}
	double qiuZC() {
		return 2*PI*r;
	}
	double qiuMJ() {
		return r*PI*r;
	}
	void show() {
		System.out.println("圆形:半径="+r);
	}
}
class Square03 extends Shape03{
	private double bianChang;
	Square03(double bianChang) {this.bianChang=bianChang;}
	double qiuZC() {
		return 4*bianChang;
	}
	double qiuMJ() {
		return bianChang*bianChang;
	}
	void show() {
		System.out.println("正方形:边长="+bianChang);
	}
}
class Rect03 extends Shape03{
	private double chang,kuan;
	Rect03(double chang,double kuan) {this.chang=chang;this.kuan=kuan;}
	double qiuZC() {
		return 2*(chang+kuan);
	}
	double qiuMJ() {
		return chang*kuan;
	}
	void show() {
		System.out.println("长方形:"+chang+":"+kuan);
	}
}
  • 总结
//使用场景4:定义数组元素类型时 定义为父类类型 这样就可以装任意子类类型的对象

总而言之

//使用场景1:定义方法参数列表时 定义为父类类型 这样就可以传递任意子类类型的对象
//使用场景2:定义成员变量时 定义为父类类型 这样就可以赋值任意子类类型的对象
//使用场景3:定义方法返回值类型时 定义为父类类型 这样就可以返回任意子类类型的对象
//使用场景4:定义数组元素类型时 定义为父类类型 这样就可以装任意子类类型的对象
在方法参数列表、方法返回值类型、类的成员变量、数组元素类型时 都定义为父类类型 这样就可以传递、返回、赋值、装任意子类类型的对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值