1. 向上造型:
- 超类型的引用指向派生类的对象
- 能点出来什么,看引用的类型-------------这是规定,记住就可以了
package ooday04;
//向上造型的演示
public class UploadDemo {
public static void main(String[] args) {
Aoo o1 = new Aoo();
o1.a = 1;
o1.show();
//o1.b = 2; //编译错误,超类不能访问派生类的
//o1.test(); //编译错误
Boo o2 = new Boo();
o2.b = 1;
o2.test();
o2.a = 2; //正确,派生类可以访问超类的
o2.show(); //正确
Aoo o3 = new Boo(); //向上造型
o3.a = 1;
o3.show();
//o3.b = 2; //编译错误,能点出来什么,看引用的类型
//o3.test(); //编译错误
}
}
class Aoo{
int a;
void show(){
}
}
class Boo extends Aoo{
int b;
void test(){
}
}
Person[] ps = new Person[7];
ps[0] = new Student("zhangsan",25,"LF","111"); //向上造型
ps[1] = new Student("lisi",24,"JMS","222");
ps[2] = new Student("wangwu",26,"SD","333");
ps[3] = new Teacher("zhaoliu",36,"SX",20000.0);
ps[4] = new Teacher("sunqi",45,"LF",30000.0);
ps[5] = new Doctor("qinba",46,"JMS","主任医师");
ps[6] = new Doctor("gaojiu",35,"SD","主治医师");
for(int i=0;i<ps.length;i++){ //遍历所有人
ps[i].sayHi(); //每个人都跟大家问好
}
2. 方法的重写(override/overriding):重新写、覆盖
- 发生在父子类中,方法名相同,参数列表相同
- 重写方法被调用时,看对象的类型-------这是规定,记住就可以了
class 餐馆{
void 做餐(){ 做中餐 }
}
//1)我还是想做中餐---------------不需要重写
class Aoo extends 餐馆{
}
//2)我想改做西餐-----------------需要重写
class Aoo extends 餐馆{
void 做餐(){ 做西餐 }
}
//3)我想在中餐基础之上加入西餐-----需要重写(先super中餐,再加入西餐)
class Aoo extends 餐馆{
void 做餐(){
super.做餐();
做西餐
}
}
public class Test {
public static void main(String[] args) {
//将学生/老师/医生统一装到Person数组中,只需要一个for即可
//向上造型的好处----实现了代码复用,后期扩展、维护也相当方便
Person[] ps = new Person[7];
ps[0] = new Student("zhangsan",25,"LF","111"); //向上造型
ps[1] = new Student("lisi",24,"JMS","222");
ps[2] = new Student("wangwu",26,"SD","333");
ps[3] = new Teacher("zhaoliu",36,"SX",20000.0);
ps[4] = new Teacher("sunqi",45,"LF",30000.0);
ps[5] = new Doctor("qinba",46,"JMS","主任医师");
ps[6] = new Doctor("gaojiu",35,"SD","主治医师");
for(int i=0;i<ps.length;i++){ //遍历所有人
ps[i].sayHi(); //每个人都跟大家问好
}
//能点出什么来,和,到底调用的是哪个-----一定要分开看
//重写方法被调用时,看对象的类型
Student z = new Student("zhangsan",25,"LF","111");
Person p = new Student("zhangsan",25,"LF","111");
z.sayHi(); //调用Student类的sayHi()
p.sayHi(); //调用Student类的sayHi()
}
}
class Person{
String name;
int age;
String address;
Person(String name,int age,String address){
this.name = name;
this.age = age;
this.address = address;
}
void sayHi(){
System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address);
}
}
class Student extends Person{
String stuId; //学号
Student(String name,int age,String address,String stuId){
super(name,age,address);
this.stuId = stuId;
}
void sayHi(){
System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address+",学号为"+stuId);
}
}
class Teacher extends Person{
double salary; //工资
Teacher(String name,int age,String address,double salary){
super(name,age,address);
this.salary = salary;
}
void sayHi(){
System.out.println("大家好,我叫"+name+",今年"+age+"岁了,家住"+address+",工资为"+salary);
}
}
class Doctor extends Person{
String level; //职称
Doctor(String name,int age,String address,String level){
super(name,age,address);
this.level = level;
}
}
- 重写需要遵循"两同两小一大"原则:-------了解,一般都是一模一样的
- 两同:
- 方法名相同
- 参数列表相同
- 两小:
- 派生类方法的返回值类型小于或等于超类方法的
- void和基本类型时,必须相同
- 引用类型时,小于或等于
- 派生类方法抛出的异常小于或等于超类方法的---------------API时讲
- 派生类方法的返回值类型小于或等于超类方法的
- 一大:
- 派生类方法的访问权限大于或等于超类方法的---------------下次课讲
//超类大,派生类小
class Coo{
void show(){}
double test(){ return 0.0; }
Student say(){ return null; }
Person sayHi(){ return null; }
}
class Doo extends Coo{
//int show(){ return 1; } //编译错误,void时必须相同
//int test(){ return 0; } //编译错误,基本类型时必须相同
//Person say(){ return null; } //编译错误,引用类型时必须小于或等于
Student sayHi(){ return null; } //正确,Student小于Person
}
3. 重写与重载的区别:
- 重写(override/overriding):
- 发生在父子类中,方法名相同,参数列表相同
- 重载(overload/overloading):
- 发生在同一类中,方法名相同,参数列表不同
4. 潜艇游戏第四天:
- 将侦察潜艇数组、鱼雷潜艇数组、水雷潜艇数组统一组合成SeaObject数组,并测试
- 在6个派生类中重写move()移动,并测试
- 画窗口:----------在World类中
- import JFrame+JPanel
- 设计World类继承JPanel-----------这步特别容易忘记
- main中代码:CV大法
4.1列表展示
4.2Battleship类
package cn.tedu.submarine;
import java.util.Objects;
/**
* 战舰
*/
public class Battleship extends SeaObject{
/**
* 命
*/
private int life;
public Battleship() {
super(66,26,270,124,5);
this.life = 5;
}
@Override
public void move() {
}
/**
* 发射炸弹的方法
*/
public void shootBomb(){
}
}
4.3Bomb类
package cn.tedu.submarine;
import java.util.Objects;
/**
* 炸弹
*/
public class Bomb extends SeaObject{
public Bomb(int x , int y) {
super(9,12,x,y,3);
}
/**
* 炸弹移动的方法
*/
@Override
public void move() {
y += speed;
}
}
4.4Mine类
package cn.tedu.submarine;
import java.util.Objects;
/**
* 水雷
*/
public class Mine extends SeaObject{
public Mine(int x , int y) {
super(11,11,x,y,1);
}
/**
* 水雷移动的方法
*/
@Override
public void move() {
y-=speed;
}
}
4.5MineSubMarine类
package cn.tedu.submarine;
import java.util.Objects;
import java.util.Random;
/**
* 水雷潜艇
*/
public class MineSubmarine extends SeaObject{
public MineSubmarine() {
super(63,19);
}
@Override
public void move() {
x+=speed;
}
}
4.6ObserverSubMarine类
package cn.tedu.submarine;
import java.util.Objects;
import java.util.Random;
/**
* 侦察潜艇
*/
public class ObserverSubmarine extends SeaObject{
public ObserverSubmarine() {
super(63,19);
}
@Override
public void move() {
x+=speed;
}
}
4.7TorpedoSubmarine类
package cn.tedu.submarine;
import java.util.Objects;
import java.util.Random;
/**
* 鱼类潜艇
*/
public class TorpedoSubmarine extends SeaObject{
public TorpedoSubmarine() {
super(64,20);
}
/**
* 鱼类潜艇移动的方法
*/
@Override
public void move() {
x+=speed;
}
}
4.8SeaObject类
package cn.tedu.submarine;
import java.util.Random;
/**
* 海洋对象
*/
public abstract class SeaObject {
/**
* 宽
*/
protected int width;
/**
* 高
*/
protected int height;
/**
* x轴
*/
protected int x;
/**
* y轴
*/
protected int y;
/**
* 速度
*/
protected int speed;
public SeaObject(int width,int height,int x , int y,int speed){
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.speed = speed;
}
public SeaObject(int width,int height){
this.width = width;
this.height = height;
Random rand = new Random();
x = -width;
y = rand.nextInt(479-height-150+1 ) +150;
this.speed = rand.nextInt(3)+1;
}
/**
* 移动的方法
*/
public abstract void move();
}
4.9World(测试类)
package cn.tedu.submarine;
import javax.swing.*;
/**
* 整个游戏世界
*/
public class World extends JPanel {
public static void main(String[] args) {
JFrame frame = new JFrame();
World world = new World();
world.setFocusable(true);
frame.add(world);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(641+16,479+39);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
/*
ObserverSubmarine os = new ObserverSubmarine();
System.out.println("原始数据---- x:"+os.x+",y:"+os.y+",speed:"+os.speed);
os.move();
System.out.println("移动后数据---- x:"+os.x+",y:"+os.y+",speed:"+os.speed);
TorpedoSubmarine ts = new TorpedoSubmarine();
System.out.println("原始数据---- x:"+ts.x+",y:"+ts.y+",speed:"+ts.speed);
ts.move();
System.out.println("移动后数据---- x:"+ts.x+",y:"+ts.y+",speed:"+ts.speed);
MineSubmarine ms = new MineSubmarine();
System.out.println("原始数据---- x:"+ms.x+",y:"+ms.y+",speed:"+ms.speed);
ms.move();
System.out.println("移动后数据---- x:"+ms.x+",y:"+ms.y+",speed:"+ms.speed);
Bomb b = new Bomb(150,300);
System.out.println("原始数据---- x:"+b.x+",y:"+b.y+",speed:"+b.speed);
b.move();
System.out.println("移动后数据---- x:"+b.x+",y:"+b.y+",speed:"+b.speed);
Mine m = new Mine(100,120);
System.out.println("原始数据---- x:"+m.x+",y:"+m.y+",speed:"+m.speed);
m.move();
System.out.println("移动后数据---- x:"+m.x+",y:"+m.y+",speed:"+m.speed);
// Battleship s = new Battleship();
// System.out.println(s.x+","+s.y+","+s.speed);
// s.move();
// SeaObject[] subMarines = new SeaObject[5];
// subMarines[0] = new ObserverSubmarine();
// subMarines[1] = new MineSubmarine();
// subMarines[2] = new TorpedoSubmarine();
// subMarines[3] = new ObserverSubmarine();
// subMarines[4] = new TorpedoSubmarine();
//
// for (int i = 0; i < subMarines.length; i++) {//遍历所有的潜艇
// SeaObject so = subMarines[i];
// System.out.println(so.x+","+so.y+","+so.speed);
// subMarines[i].move();
// }
//
// ObserverSubmarine[] oses = new ObserverSubmarine[3];
// oses[0] = new ObserverSubmarine();
// oses[1] = new ObserverSubmarine();
// oses[2] = new ObserverSubmarine();
// for (int i = 0; i < oses.length; i++) {
// System.out.println(oses[i].x+","+oses[i].y+","+oses[i].speed);//输出每个侦察挺的x和y坐标
// oses[i].move();
// }
// Bomb[] bs = new Bomb[3];
// bs[0] = new Bomb(100,522);
// bs[1] = new Bomb(145,243);
// bs[2] = new Bomb(113,443);
// for (int i = 0; i < bs.length; i++) {
// Bomb b = bs[i];
// System.out.println(b.x+","+b.y+","+b.speed);
// bs[i].move();
// //炸弹移动
// //炸弹打潜艇
// }
//
// Mine[] ms = new Mine[2];
// ms[0] = new Mine(241,22);
// ms[1] = new Mine(341,112);
// for (int i = 0; i < ms.length; i++) {
// Mine m = ms[i];
// System.out.println(m.x+","+m.y+","+m.speed);
// ms[i].move();
// }
*/
}
}
5. 补充:
继承要符合is(是)的关系
5.1超类的意义:
- 封装共有的属性和行为------------------代码复用
- 为所有派生类提供统一的类型---------向上造型(代码复用)
5.2 明日单词:
1)override:重写
2)package:包
3)import:导入
4)public:公开的
5)protected:受保护的
6)private:私有的
7)card:卡
8)id:号码
9)password/pwd:密码
10)balance:余额
11)pay:支付
12)money:金额
13)check:检查
14)static:静态的
15)image:图片
16)icon:图标
17)get:获取
18)status:状态