java面向对象:三大特性:封装,继承,多态

———————————————————————————————————
面向对象:三大特性:封装,继承,多态
———————————————————————————————————
1.什么是类?什么是对象?
1)现实世界是由很多很多对象组成的
基于对象抽出了类
2)对象:真实存在的单个的个体
类:类别/类型,代表一类个体
3)类中包含:
3.1)所有对象所共有的属性/特征----------成员变量
3.2)所有对象所共有的行为---------------方法
4)一个类可以创建多个对象
同一类型所创建的对象,结构相同,数据不同
5)类是对象的模板,对象是类的具体的实例
2.如何创建类?如何创建对象?如何访问成员?

练习:
1)参与的角色:英雄机、小敌机、大敌机、小蜜蜂、子弹、天空
2)关系:英雄机发射子弹
子弹射击敌人(小敌机、大敌机、小蜜蜂)
英雄机与敌人(小敌机、大敌机、小蜜蜂)碰撞
英雄机、小敌机、大敌机、小蜜蜂、子弹都是在天空上飞
3)英雄机发射子弹分单倍火力(火力值=0)和双倍火力(火力值>0)
发射一次双倍火力,则火力值减2
4)子弹射击敌人:
子弹消失、敌人爆破后消失
打掉小敌机---------玩家得1分
打掉大敌机---------玩家得3分
打掉小蜜蜂---------英雄机得奖励(1条命或40火力值)
5)英雄机和敌人碰撞:
敌人消失
英雄机减1条命+英雄机清空火力值
6)当英雄机的命数为0时,游戏结束
7)项目四种状态:启动、运行、暂停、游戏结束

设计射击游戏中的对象类:
1)先找对象:英雄机、小敌机、大敌机、小蜜蜂、子弹、天空
2)抽类:Hero、Airplane、BigAirplane、Bee、Bullet、Sky
3)设计类中的成员变量和方法
4)创建对象并测试

————————————————————————————————
0.方法的签名: 方法名+参数列表
1.方法的重载(overload):
1)发生在一个类中,方法名称相同,参数列表不同,方法体不同
2)编译器在编译时根据方法的签名自动绑定调用的方法
2.构造方法:
1)给成员变量赋初值
2)与类同名,没有返回值类型
3)在创建(new)对象时被自动调用
4)若自己不写构造,则默认一个无参构造方法
若自己写了构造,则不再默认提供了
5)构造方法可以重载
3.this:指代当前对象,哪个对象调用方法指的就是哪个对象
只能用在方法中,在方法中访问成员变量之前默认有个this.
this的用法:
1)this.成员变量名-------------访问成员变量
2)this.方法名()---------------调用方法(一般不用)
3)this()----------------------调用构造方法
4.null:空,没有指向任何对象
若引用的值为null,则该引用不能再进行任何操作了
若操作则发生NullPointerException空指针异常
5.引用类型之间画等号:
1)指向同一个对象
2)通过一个引用对数据的修改会影响另一个引用对数据的访问
eg:房子钥匙
基本类型之间画等号:
1)赋值
2)对一个变量的修改不会影响另一个变量
eg:身份证复印件
房子:对象
房子钥匙:引用
配一把钥匙:引用
内存管理:由JVM来管理的
1)堆:存储new出来的对象(包括成员变量)
2)栈:存储局部变量(包括方法的参数)
3)方法区:存储.class字节码文件(包括方法)

练习:
给Hero、Airplane、BigAirplane、Bee、Bullet、Sky
分别添加构造方法
————————————————————————————
1.引用类型数组:
1)Student[] stus = new Student[3]; //创建Student数组对象
stus[0] = new Student(“zhangsan”,25,“LF”); //创建Student对象 并调用Student
stus[1] = new Student(“lisi”,26,“JMS”);
stus[2] = new Student(“wangwu”,28,“SD”);
System.out.println(stus[0].address);
2)Student[] stus = new Student[]{
new Student(“zhangsan”,25,“LF”),
new Student(“lisi”,26,“JMS”),
new Student(“wangwu”,28,“SD”)
};
3)int[][] arr = new int[3][];-----------数组的数组
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[2];
arr[1][0] = 100;
4)int[][] arr = new int[3][4];----------数组的数组
for(int i=0;i for(int j=0;j arr[i][j] = (int)(Math.random()*100);
}
}
例如:
int[][] arr= new int[3][];//[3]是数组长度,[]代表每一个数组中都长度
arr[0] = new int[2]; //第一个数组的长度为2
arr[1] = new int[3]; //第二个数组都长度为3
arr[2] = new int[4];
arr[1][2] = 100; // 给第2个数组中第3个元素赋值为100
System.out.println(arr[1][2]);//输出第二个数组中第三个
int[][] arr1 = new int[3][4]; //一共有3个组数,每个数组都长度为4
for(int i = 0;i for(int j = 0;j arr1[i][j] = 250; // 给每一个数组赋值为250
System.out.println(arr1[i][j]);
2.继承:
1)作用:代码复用
2)通过extends来实现继承
3)超类/父类:所有派生类所共有的属性和行为
派生类/子类:派生类所特有的属性的行为
4)派生类继承超类后,派生类具有:派生类的+超类的
5)一个超类可以有多个派生类
一个派生类只能有一个超类-------单一继承
6)继承具有传递性
7)java规定:构造派生类之前必须先构造超类
在派生类的构造方法中若没有调用超类的构造方法
------则默认super()调用超类的无参构造方法
在派生类的构造方法中若调用了超类的构造方法
------则不再默认提供
注意:super()调用超类构造必须位于派生类构造的第一行
3.super:指代当前对象的超类对象
super的用法:
1)super.成员变量名------------访问超类的成员变量
2)super.方法名()--------------调用超类的方法-------明天讲
3)super()---------------------调用超类的构造方法
例:
class Person { //class创建类。
//超类/父类
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 {//派生类/子类 使用extends继承
String stuId;
Student(String name, int age, String address, String stuId) {
super(name, age, address); // super调用超类的值
this.stuId = stuId; // this. 给stuld赋值。 super的超类已经赋过,所以不需要再赋值
}}

练习:
1.创建Person类,包含:
1)成员变量:name,age,address
2)构造方法:Person(3个参数){}
3)方法:sayHi(){输出3个数据}
2.创建Student类,继承Person,包含:
1)成员变量:stuId
2)构造方法:Student(4个参数){}
3.创建Teacher类,继承Person,包含:
1)成员变量:salary
2)构造方法:Teacher(4个参数){}
4.创建Doctor类,继承Person,包含:
1)成员变量:level
2)构造方法:Doctor(4个参数){}
5.创建Test类,main中:
1)创建Student数组ss,填充数据,遍历问好
2)创建Teacher数组ts,填充数据,遍历问好
3)创建Doctor数组ds,填充数据,遍历问好

     public class Test {
	public static void main(String[] args) {
		Person[] ps = new Person[3];
		ps[0] = new Student("张发阳",22,"宝兴", "1634");
		ps[1] = new Teacher("张三", 35, "浙江", 4122);
		ps[2] = new Doctor("李四", 46, "上海", "aaa");
		for(int i=0;i<ps.length;i++){
			ps[i].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 sayHi() {
		System.out.println("我职业是医生,名叫" + name + "," + "今年" + age + "岁了,家住" + address + ",任职:" + level);
	}
}

——————————————————————————————
2018/8/14
1.向上造型;
1)超类型的引用指向派生类的对象
2)能点出来什么,看引用的类型
例:

  	public static void main(String[] args) {
		Aoo o1 = new Aoo();
		o1.a = 1;
		o1.show();
		//o1.b = 2; //编译错误,超类不能访问派生类的	
		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; //编译错误,能点出来什么,看引用的类型
	}}
            class Aoo{
	int a;
	void show() {}
}
          class Boo extends Aoo{
	int b;
	void test() {}
}

2.方法的重写(Override):重新写,覆盖
  1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
  2)重写发放被调用时,看对象的类型
   //超类大,派生类小
        class Coo{
	void show() {}
	double test() {return 0.0;}
	Doo say() {return null;}
	Coo sayHi() {return null;}
}
               class Doo extends Coo{
	//int show() {return 1;} //编译错误,void时必须相等
	//int test() {return 0;} //编译错误,基本类型时必须相等
	//Coo say() {return null;} //编译错误,引用类型必须小于或等于
	Doo sayHi() {return null;} //正确
                      }
3.重写与重载的区别:-----常见面试题
  1)重写:
    1.1)发生在父子类中,方法名称相同,参数列表相同,方法体不同
     1.2)遵循“运行期绑定”,看对象的类型来调用方法
     class Eoo{
	void show() { //方法
		System.out.println("超类show");
	}}
      class Foo extends Eoo{
	void show() { //方法重写
		System.out.println("派生类show");
	}}
  2)重载:
     2.1)发生在一个类中,方法名称相同,参数列表不同,方法体不同
     2.2)遵循“编译期绑定",看参数/引用的类型来绑定方法
      class Aoo(){    //??方法重载
      void say(int age){System.out.println("你好,我今年"+age+"岁了");}
      void sa(String name){System.out.println("你好,我叫"+name);}
      void sa(String name,String address){"你好,我叫"+name+",家住"+address);}    
}

//重写的演示
	public static void main(String[] args) {
		Goo goo = new Goo();
		Eoo o = new Foo();
		goo.test(o); //重载看参数/引用Eoo
	}
}
     class Goo{
	void test(Eoo o) {  
		System.out.println("超类型参数");
		o.show(); //重写看对象Foo
             }
	void test(Foo o) { 
		System.out.println("派生类型参数");
		o.show();
	}}
    class Eoo{
	void show() { //方法
		System.out.println("超类show");
	}}
     class Foo extends Eoo{
	void show() { //方法重写
		System.out.println("派生类show");
	}}

练习:
/1.创建Person类,包含:
1)成员变量:name,age,address;
2)构造方法:Person(3个参数){}
3)方法:sayHi{输出3个数据}
2.创建Student类,继承Person,包含:
1)成员变量:stuId
2)构造方法:Student(4个参数){}
3)方法:重写sayHi(){输出4个数据}
3.创建Teacher类,继承Person,包含:
1)成员变量:salary
2)构造方法:Teacher(4个参数){}
3)方法:重写sayHi(){输出4个数据}
4.创建Doctor类,继承Person,包含:
1)成员变量:lever
2)构造方法:Doctor(4个参数){}
3)方法:重写sayHi(){输出4个数据}
5.创建Test类,main中:
创建Person数组ps,填充数据,遍历问好
/

  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{
	int stuId;
	Student(String name,int age,String address,int 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 sayHi(){
		System.out.println("我的职业是医生,名为"+name+",今年"+age+"岁了,家住"+address+",任职:"+level);
	}
}

     public class Test {
	  public static void main(String[] args){  
		  Person[] ps = new Person[4];
		  ps[0] = new Person("张发阳",20,"宝兴兴兴");
		  ps[1] = new Student("张发阳",25,"宝兴",1634);
		  ps[2] = new Doctor("张发阳",35,"宝兴兴","副院长");
		  ps[3] = new Teacher("张发阳",45,"宝兴兴兴",3000);		 
		  for(int i =0;i<ps.length;i++){
			  ps[i].sayHi();
		  }			  
	  }}

———————————————————————————————————
笔记:
1.package:
1)作用:避免类名的冲突
2)包名可以有层次结构
3)类的全称: 包名.类名,同包中的类不能同名
4)建议:包名所有字母都小写
package a;
class Aoo{ } //全称a.Aoo
package b;
class Aoo{ } //全称b.Aoo 不在一个包,所以不报错
class Aoo{ } //错误,一个包里不可以重复类名

import:
1)同包中的类可以直接访问,
不同包中的类不能直接访问,想访问有如下两种方式:
1.1)先import声明类再直接使用类------建议
import oo.day05.Aoo; //声明类
public class Coo {
void show() {
Aoo o = new Aoo();
o.a = 1;
}}
1.2)类的全称------------------------太繁琐、不建议
void show() {
oo.day05.Aoo o = new oo.day05.Aoo();
oo.day05.Aoo.a = 1;
2.访问控制修饰符:
1)public:公开的,任何类
2)private:私有的,本类
3)protected:受保护的,本类、派生类、同包类
4)默认的:什么也不写,本类、同包类
说明:
1)类的访问修饰符只能是public或默认的
2)类中成员的访问修饰符如上四种都可以
修饰符 本类 同一个包中的类 子类 其他类
public 可以访问 可以访问 可以访问 可以访问
private 可以访问 不能访问 不能访问 不能访问
protected 可以访问 可以访问 可以访问 不能访问
默认 可以访问 可以访问 可以访问 不能访问
例:
public int a; //任何类
protected int b; //本类、派生类、同包类
int c; //本类、同包类
private int d; //本类
void show() {
a = 1;
b = 2;
c = 3;
d = 4;
}}
//演示private
class Boo{
void show() {
Aoo o = new Aoo();
o.a = 1;
o.b = 2;
o.c = 3;
//o.d = 4;
}}

3.final:最终的、不可改变的----应用率低
1)修饰变量:变量不能被改变
//演示final修饰方法
//演示final修饰变量
class Eoo{
final int a = 5;
final int b;
Eoo(){
b = 6;
}
void show() {
final int c;
//a = 55; //编译错误,final的变量不能被改变
}}

2)修饰方法:方法不能被重写
class Foo{
final void show() {}
void test() {}
}
class Goo extends Foo{
//void show() {} //编译错误,final修饰的方法不能被重写
void test() {}
}

3)修饰类:类不能被继承
//演示final修饰类
final class Hoo{}
//class Ioo extends Hoo{} //编译错误,final修饰的类不能被继承
class Joo{}
final class Koo extends Joo{}
4.static:静态的
1)静态变量:
1.1)由static修饰
1.2)属于类的,存储在方法区中,只有一份
1.3)常常通过类名点来访问
1.4)何时用:所有对象所共享的数据(图片、音频、视频等)
2)静态方法:
2.1)由static修饰
2.2)属于类的,存储在方法区中,只有一份
2.3)常常通过类名点来访问
2.4)静态方法没有隐式this传递,
静态方法中不能直接访问实例成员
2.5)何时用:方法的操作仅与参数相关而与对象无关
3)静态块:
3.1)属于类的,在类被加载期间自动执行,
类只被加载一次,所以静态块只执行一次
3.2)何时用:用于加载/初始化静态资源(图片、音频、视频等)
//static的演示
public static void main(String[] args) {
Loo o1 = new Loo();
o1.show();
Loo o2 = new Loo();
o2.show();
System.out.println(Loo.b); //2,建议类名点来访问
Moo.test(); //类名点来访问
Noo o4 = new Noo();
Noo o5 = new Noo();
}}
//演示静态块
class Noo{
static {
System.out.println(“静态块”);
}
Noo(){
System.out.println(“构造方法”);
}}
//演示静态方法
class Moo{
int a;
static int b;
void show() { //有this
System.out.println(this.a);
System.out.println(Moo.b);
}
static void test() { //没有this
//静态方法没有隐式this传递
//没有this意味着没有对象
//而实例变量a必须通过对象点来访问
//结论:静态方法中不能直接访问实例成员
//System.out.println(a); //编译错误
System.out.println(Moo.b);
}}
//演示静态变量
class Loo{
int a;
static int b;
Loo(){
a++;
b++;
}
void show() {
System.out.println(“a=”+a+",b="+b);
}}

内存管理: (背)
1)堆:new出来的对象(包括实例变量)
2)栈:局部变量(包括方法的参数)
3)方法区:.class字节码文件(包括方法、静态变量)
例:成员变量:
1)实例变量:没有static修饰,属于对象的,存储在堆中,
有几个对象就有几份
通过对象名点来访问
2)静态变量:由static修饰,属于类的,存储在方法区中,
只有一份
通过类名点来访问
—————————————————————————————
笔记:
1.static final常量:
1)必须声明同时初始化
2)类名点来访问、不能被改变
3)建议:常量名所有字母都大写,多个单词之前用_分隔
4)编译器在编译时将常量直接替换为具体的值,效率高
5)何时用:数据永远不变,并且经常使用
2.抽象方法:
1)由abstract修饰
2)只有方法的定义,没有具体的实现(连{}都没有)
3.抽象类:
1)由abstract修饰
2)包含抽象方法的类必须是抽象类
不包含抽象方法的类也可以声明为抽象类------我乐意
3)抽象类不能被实例化 ,但数组可以
4)抽象类是需要被继承的,派生类:
4.1)重写抽象类中的所有抽象方法-----建议
4.2)也声明为抽象类-----------------一般不这样做
5)抽象类的意义:
5.1)封装共有的属性和行为--------------代码复用
5.2)为所有派生类提供统一的类型--------向上造型
5.3)可以包含抽象方法,为所有派生类提供统一的入口,
派生类的具体实现不同,但入口是一致的

设计规则:
1)将派生类共有的属性和行为,抽到超类中--------抽共性
2)派生类的行为都一样,设计为普通方法
派生类的行为都不一样,设计为抽象方法
————————————————————————————————
常见面试题:
问: 内部类有独立.class吗?
答: 有
例:Mama$(发音:多嘞儿)baby.class //Mama外部类,baby内部类
1.成员内部类:应用率不高
1)类中套类,外面的称为Outer外部类,里面的成为Inner内部类
Class Aoo{ //外部类
Class Boo{//内部类
}}
使用方法:
public static void main(String[] args) {
Demo14 a = new Demo14();
Foo f = a.new Foo();
f.Doo();
}
2)内部类通常只服务于外部类,对外不具备可见性
3)内部类对象通常是在外部类中创建的
4)内部类中可以直接访问外部类的成员(包括私有的)
内部类中有个隐式的引用指向了创建它的外部类对象
eg: 外部类名.this
2.匿名内部类:
1)若想创建一个类(派生类)的对象,并且对象只创建一个,
此时该类不必命名,称为匿名内部类
2)在jdk1.8以前,匿名内部类中若想访问外面的变量,
该变量必须是final的

功能实现过程:
1.先写行为/方法:
1)若为某个对象所特有的行为,就将方法设计在对应的类中
2)若为所有对象所共有的行为,就将方法设计在超类中
2.页面/窗口调用:
1)若为定时触发的,则在定时器中调用
2)若为事件触发的,则在侦听器中调用

程序的运行结果与你所预期的结果不同:
1)打桩: System.out.println(数据);
2)Debug调试:
————————————————————————————————
笔记:
1.接口:
1)是一种数据类型(引用类型)
2)由interface定义
3)只能包含常量和抽象方法
4)接口不能被实例化
5)接口是需要被实现/继承的,实现类/派生类:
必须重写所有抽象方法
6)一个类可以实现多个接口,用逗号分隔
若又继承又实现时,应先继承后实现
7)接口继承接口(可以继承多个接口)

设计规则:
1)将所有派生类所共有的属性和行为,抽到超类中-----抽共性
2)派生类的行为都一样,设计为普通方法
派生类的行为都不一样,设计为抽象方法
3)将部分派生类所共有的行为,抽到接口中
符合既是也是原则时,需使用接口
接口是对继承单根性的扩展----------实现多继承
————————————————————————————
笔记:
1.多态:
1)多态的意义: //抽象方法一定是多态
1.1)同一类型的引用指向不同的对象时,有不同的实现
----行为的多态:cut()、run()、step()…
1.2)同一个对象被造型为不同的类型时,有不同的功能
----对象的多态:我、你、水…
2)向上造型/自动类型转换:
2.1)超类型的引用指向派生类的对象
2.2)能造型成为的类型有: 超类+所实现的接口
2.3)能点出来什么,看引用的类型
3)强制类型转换,成功的条件只有如下两种:
3.1)引用所指向的对象,就是该类型
3.2)引用所指向的对象,实现了该接口或继承的该类
4)强转时若不符合如上条件,则发生ClassCastException类型转换异常,
建议在强转之前先通过instanceof(实例)来判断引用的对象是否是该类型

基本类型之间强制类型转换,
---------一定正确,但有可能溢出或丢失精度
引用类型之间强制类型转换,
---------有可能会失败报错

超类大,派生类小
自动:小类型到大类型
强制:大类型到小类型
—————————————————————————————————
正课:
1.内存管理:由JVM来管理的------了解
1)堆:
1.1)存储new出来的对象(包括实例变量)
1.2)垃圾:没有任何引用指向的对象
垃圾回收器(GC)不定时到内存中清扫垃圾,
回收过程是透明的(看不到的),
不一定一发现垃圾就立刻回收,
调用System.gc()可以建议JVM尽快调度GC来回收
1.3)内存泄漏:不再使用的对象还没有被及时的回收
建议:对象不再使用时应及时将引用设置为null
1.4)实例变量的生命周期:
创建对象时存储在堆中,对象被回收时一并被回收
2)栈:
2.1)存储正在调用的方法中的局部变量(包括方法参数)
2.2)调用方法时会为该方法在栈中分配一块对应的栈帧,
栈帧中存储局部变量(包括方法参数)
当方法调用结束时,栈帧被清除,局部变量一并失效
2.3)局部变量的生命周期:
调用方法时存储在栈中,方法结束时与栈帧一并被清除
3)方法区:
3.1)存储.class字节码文件(包括方法、静态变量)
3.2)方法只有一份,通过this来区分具体的调用对象
+++++++++++++++++++++++++++++++++++++
总结:
面向对象三大特征:
1.封装:
1)类:封装的是对象的属性和行为
2)方法:封装一段特定的是业务逻辑功能实现
3)访问控制修饰符:封装的是具体的访问权限
2.继承:
1)作用:代码复用
2)超类:所有派生类所共有的属性和行为
接口:部分派生类所共有的行为
派生类:派生类所特有的属性和行为
3)单一继承、多接口实现,传递性
3.多态:
1)意义:
1.1)行为的多态(所有抽象方法都是多态的)
1.2)对象的多态(所有对象都是多态的)
2)向上造型、强制类型转换、instanceof判断
3)多态的表现形式:
3.1)重写:根据对象的不同来表现多态
3.2)重载:根据参数的不同来表现多态

设计游戏思路(面向对象课程安排):
Shoot射击游戏第一天:
1.创建了6个对象类,创建World类测试
(理论:
1.什么是类?什么是对象?
2.如何创建类?如何创建对象?如何访问成员?
项目:
3.创建了6个对象类,并创建World类测试)

Shoot射击游戏第二天:
1.给6个对象类添加构造方法,并测试
(理论:
1.方法的重载
2.构造方法
3.this
5.null和NullPointerException
6.引用类型之间画等号
项目:
4.给6个对象类添加构造方法,并测试)

Shoot射击游戏第三天:
1.设计小敌机数组、大敌机数组、小蜜蜂数组、子弹数组,并测试
2.设计超类FlyingObject,6个对象类继承
3.给FlyingObject类设计两个构造方法,6个对象类分别调用
( 理论:
1.引用类型数组
3.继承
5.super
项目:
2.设计小敌机数组、大敌机数组、小蜜蜂数组、子弹数组,并测试
4.设计FlyingObject超类,6个对象类继承
6.给FlyingObject超类设计两个构造方法,6个对象类分别调用)

Shoot射击游戏第四天:
1.将小敌机数组、大敌机数组、小蜜蜂数组合为FlyingObject数组,并测试
2.在6个对象中重写step()
3.画窗口
(理论:
1.向上造型
3.方法的重写
4.重写与重载的区别
项目:
2.将小敌机数组、大敌机数组、小蜜蜂数组合为FlyingObject数组,并测试
5.在6个派生类中重写超类的step()方法
6.画窗口)

Shoot射击游戏第五天:
1.给类中成员添加访问控制修饰符
2.给6个对象设计图片属性
(理论:
1.package和import
2.访问控制修饰符
4.final
5.static
项目:
3.给类中成员添加访问控制修饰符
6.给6个对象设计图片属性)

Shoot射击游戏第六天:
1.设计窗口的宽和高为常量,适当地方做修改
2.画对象:
1)想画对象得获取对象的图片,每个对象都能获取图片,
意味着获取图片行为为共有行为,设计为超类FlyingObject中,
每个对象获取图片的行为都是不一样的,所以设计为抽象方法
----在FlyingObject中设计抽象方法getImage()来获取对象的图片
2)对象在获取图片时需要考虑对象在不同状态下获取不同的图片,
所以要给对象设计状态,每个对象都有状态,
所以将状态设计在超类中,而状态一般都是常量
----在FlyingObject中设计三个常量,state变量表示当前状态
在获取图片时需要先对对象的状态进行判断,
每个对象都得判断,所以将判断状态行为设计在超类中,
每个对象判断状态的方式都是一样的,所以设计为普通方法
----在FlyingObject中设计isLife()、isDead()、isRemove()来判断对象的状态
3)----重写FlyingObject中的抽象方法getImage():
3.1)天空Sky,直接返回image即可
3.2)子弹Bullet:
3.2.1)若活着的,直接返回image即可
3.2.2)若死了的,则删除
3.3)英雄机Hero:
3.3.3)若活着的,返回images[0]和images[1]的来回切换
3.4)小敌机Airplane:
3.4.1)若活着的,直接返回images[0]
3.4.1)若死了的,返回images[1]到images[4]的轮转,4后则删除
3.5)大敌机Airplane:
3.5.1)若活着的,直接返回images[0]
3.5.1)若死了的,返回images[1]到images[4]的轮转,4后则删除
3.6)小蜜蜂Airplane:
3.6.1)若活着的,直接返回images[0]
3.6.1)若死了的,返回images[1]到images[4]的轮转,4后则删除
4)图片有了则可以开画了,每个对象都能画,
意味着画为共有的行为,所以设计在超类中,
每个对象画的方式都是一样的,所以设计为普通方法
----在FlyingObject中设计paintObject()实现画对象
5)天空Sky每次需要画两张图,所以重写超类的paintObject()
----在Sky中重写paintObject()
6)在World类中调用paintObject()实现往窗口上画对象
----在World中重写paint()方法
(理论:
1.static final常量
3.抽象方法
4.抽象类
项目:
2.设计窗口的宽和高为常量,适当地方做修改
5.画对象)

Shoot射击游戏第七天:
1.敌人入场:
1)敌人是由窗口产生的,所以在World中创建nextOne()生成敌人对象
2)敌人入场为定时发生的,在run()中调用enterAction()实现敌人入场
在enterAction()中:
每400毫秒,获取敌人对象,扩容并装到最后一个元素上
2.子弹入场:
1)子弹是由英雄机发射出来的,所以在Hero中创建shoot()生成子弹对象
2)子弹入场为定时发生的,在run()中调用shootAction()实现子弹入场
在shootAction()中:
每300毫秒,获取子弹对象,扩容并数组追加
3.飞行物移动:
1)飞行物移动为所有对象所共有的行为,所以在超类中设计抽象方法step()
派生类中重写step()
2)飞行物移动为定时发生的,在run()中调用stepAction()实现飞行物移动
在stepAction()中:
天空动,遍历敌人敌人动,遍历子弹子弹动
(理论:
1.成员内部类
2.匿名内部类
项目:
3.敌人入场
4.子弹入场
5.飞行物移动)

Shoot射击游戏第八天:
1.英雄机随着鼠标移动:
1)英雄机随着鼠标动为英雄机的行为,
所以在Hero中设计moveTo()实现英雄机随着鼠标移动
2)英雄机随着鼠标动为事件触发的,所以在侦听器中重写mouseMoved()
在mouseMoved()中:
获取鼠标的x和y坐标,英雄机随着动
2.删除越界的敌人和子弹:
1)将检测敌人越界行为outOfBounds()设计在FlyingObject中,
在Bullet中重写outOfBounds()
2)删除越界行为为定时发生的,所以在run()中调用outOfBoundsAction()实现删除越界,
在outOfBoundsAction()中:
声明不越界数组,遍历敌人/子弹数组,
判断若不越界,则将不越界对象添加到不越界数组中,
最后将不越界数组复制到enemies/bullets中
3.设计Enemy得分接口,Airplane和BigAirplane实现
设计Award奖励接口,Bee实现
(理论:
3.接口
项目:
1.英雄机随着鼠标移动
2.删除越界的敌人和子弹)

Shoot射击游戏第九天:
1.敌人与子弹的碰撞:
1)在FlyingObject中设计hit()实现敌人与子弹的碰撞
在FlyingObject中设计goDead()实现飞行物去死
在Hero中设计addLife()增命、addDoubleFire()增火力
2)敌人与子弹的碰撞为定时发生的,在run()中调bulletBangAction()实现敌人与子弹的碰撞
在bulletBangAction()中:
遍历子弹得子弹,遍历敌人得敌人,判断若撞上了:
子弹去死、敌人去死
判断被撞对象:
若是Enemy,则玩家增分
若是Award,则英雄机增命或增火力
2.画分和画命:
1)在Hero中设计getLife()获取英雄机的命
2)在paint()中:画分和画命
(理论:
1.多态
项目:
2.子弹与敌人的碰撞
3.画分和画命)

Shoot射击游戏第十天:
1.英雄机与敌人的碰撞:
1)借用FlyingObject的hit()碰撞、goDead()去死
在Hero类中设计subtractLife()减命、clearDoubleFire()清空火力值
2)英雄机与敌人碰撞为定时发生的,在run()中调用heroBangAction()实现英雄机与敌人的碰撞
在heroBangAction()中:
遍历敌人得敌人,判断是否与英雄机撞上了,若撞上了:
敌人去死、英雄机减命、英雄机清空火力值
2.检测游戏结束:
1)借用Hero的getLife()获取命数
2)检测游戏结束为定时发生的,在run()在调用checkGameOverAction()检测结束
在checkGameOverAction()中:
判断当英雄机的命数<=0时,则游戏结束(将当前状态修改为游戏结束状态)
3.画状态:
1)设计四个常量表示4种状态,并设计state表示当前状态(默认为启动状态)
设计三个静态变量表示3个图片,并在static块中初始化
在paint()中,实现在不同状态下画不同的图片
2)将run中那一堆action设计为只在运行状态下才执行
将英雄机随着鼠标动设计为只在运行状态下才执行
3)重写mouseClicked()鼠标点击事件:
启动变运行、游戏结束先清理再变启动
重写mouseExited()鼠标移出事件: 运行变暂停
重写mouseEntered()鼠标移入事件: 暂停变运行
( 理论:
1.内存管理
项目:
2.英雄机与敌人的碰撞
3.检测游戏结束
4.画状态)

你可能感兴趣的:(java)