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());
}
}
abstract class Shape01{
abstract double getZC();
abstract double getMJ() ;
}
class Circle01 extends Shape01{
private double r;
public static final double PI=3.1415926;
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) {
Lamp l=new Lamp();
RedBulb01 rr=new RedBulb01();
rr.setName("红灯1号");
l.r=rr;
l.on();
l.off();
}
}
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+super.getSalary(month);
}
}
class SalesEmployee extends Employee{
double tcl;
double monthSale;
double getSalary(int month) {
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+super.getSalary(month);
}
}
class BasePlusSalesEmployee extends SalesEmployee{
double baseSalary;
double getSalary(int month) {
return baseSalary+super.getSalary(month);
}
}
3 abstract
public class Demo01Abstract {
public static void main(String[] args) {
Demo1 d1;
}
}
abstract class Demo1{
int a=1;
void hehe() {}
Demo1(){}
}
abstract class Demo2{
int a=1;
void hehe() {}
abstract void hai1();
abstract void hai2();
}
abstract class Demo2Zi1 extends Demo2{
void hai1() {}
}
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();
Fu02 fuzi=new Zi02();
System.out.println(fuzi.a+"::"+fuzi.b);
fuzi.hehe();
fuzi.haha();
}
}
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+"运动:睡觉!");
}
}
package day07_oop;
public class Demo0312DuoTaiUse {
public static void main(String[] args) {
Animal2 aa=new Dog2("二哈");
wei(aa);
wei(new Cat2("波斯猫"));
}
static void wei(Animal2 a) {
a.eat();
a.sport();
}
}
abstract class Animal2{
String name;
Animal2(String name){this.name=name;}
abstract void eat();
abstract void sport();
}
class Dog2 extends Animal2{
Dog2(String name){super(name);}
void eat() {
System.out.println("狗:"+name+"正在吃骨头!");
}
void sport() {
System.out.println("狗:"+name+"运动:抓老鼠!");
}
}
class Cat2 extends Animal2{
Cat2(String name){super(name);}
void eat() {
System.out.println("猫:"+name+"正在吃鱼!");
}
void sport() {
System.out.println("猫:"+name+"运动:晒太阳!");
}
}
使用场景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+"开始发亮:绿光");
}
}
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();
}
}
class Lamp02{
Blub02 r;
void on() {
if(r!=null) {r.faLiang();}
}
}
abstract class Blub02{
String name;
public Blub02(String name) {
this.name = name;
}
public abstract void faLiang();
}
class RedBlub02 extends Blub02{
public RedBlub02(String name) {
super(name);
}
public void faLiang() {
System.out.println("我是红灯:"+name+"开始发亮:红光");
}
}
class GreenBlub02 extends Blub02{
public GreenBlub02(String name) {
super(name);
}
public void faLiang() {
System.out.println("我是绿灯:"+name+"开始发亮:绿光");
}
}
使用场景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);
}
}
abstract class Shape02{
abstract double qiuZC();
abstract double qiuMJ();
abstract void show();
}
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;
}
}
abstract class Shape03{
abstract double qiuZC();
abstract double qiuMJ();
abstract void show();
}
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:定义数组元素类型时 定义为父类类型 这样就可以装任意子类类型的对象
在方法参数列表、方法返回值类型、类的成员变量、数组元素类型时 都定义为父类类型 这样就可以传递、返回、赋值、装任意子类类型的对象