语言基础
1.Java开发环境:
1)java编译运行过程:(常见面试题)
1.1)编译期:.java源文件,经过编译,生成.class字节码文件
1.2)运行期:JVM加载.class并运行.class 特点:跨平台、一次编程到处使用
2)名词解释:(常见面试题)
2.1)JVM:java虚拟机:加载.class并运行.class
2.2)JRE:java运行环境
除了包含JVM以外还包含了运行java程序所必须的环境 JRE=JVM+java系统类库(小零件)
2.3)JDK:java开发工具包
除了包含JRE以外还包含了开发java程序所必须的命令工具 JDK=JRE+编译、运行等命令工具
说明:
1)运行java程序的最小环境JRE
2)开发java程序的最小环境JDK
3)配置环境变量:(了解)
3.1)JAVA_HOME:指向jdk的安装路径
3.2)CLASSPATH:表示类的搜索路径,一般简写为.
3.3)PATH:指向jdk下的bin目录
2.eclipse:
1)IBM、开源的、免费的、不需要安装仅需解压即可
2)开发步骤:
2.1)新建Java项目/工程(project)--------------小区
2.2)新建Java包(package)---------------------楼+单元
2.3)新建Java类(class)---------------------房子
3)注释:解释性文本 3.1)单行注释:// 3.2)多行注释:/* */ 3.3)文档注释:/** */------------API时
3.变量:存数的,代词,指代的就是它所存的那个数
1)变量的声明:
int a; //声明一个整型的变量,名为a
int b,c,d; //声明三个整型的变量,名为b,c,d
2)变量的初始化:第一次赋值
int a = 250; //声明整型变量a并赋值为250
int b; //声明整型变量b
b = 250; //给变量b赋值为250
3)变量的使用:
3.1)对变量的操作就是对它所存的那个数的操作
int a = 5; int b = a+10; //取出a的值5,加10后,再赋值给整型变量b
System.out.println(b); //输出变量b的值15
System.out.println("b"); //输出b,双引号中的原样
输出 a = a+10; //在a本身基础之上增10
System.out.println(a); //输出变量a的值15
3.2)变量的操作必须与数据类型匹配
int a = 3.14; //编译错误,数据类型不匹配
3.3)变量在使用之前必须声明并初始化
System.out.println(m); //编译错误,m未声明
int m; System.out.println(m); //编译错误,m未初始化
4)变量的命名:
4.1)只能包含字母、数字、_和$,并且不能以数字开头
4.2)严格区分大小写
4.3)不能使用关键字
4.4)可以中文命名,但不建议 建议英文的见名知意、驼峰命名法
//类名是帕斯卡命名法,所有单词首字母大写
4.基本数据类型:
1)int:整型:4个字节(32位),只能装整数,-21个多亿到21个多亿
1.1)整数直接量默认为int类型,但不能超范围,超范围则编译错误
1.2)两个整数相除,结果还是整数,小数位无条件舍弃(不会四舍五入)
1.3)整数运算时若超出范围,则发生溢出(溢出不是错误,但是是需要避免的)//最大值溢出后到最小值,但正数溢出不一定是负数
2)long:长整型,8个字节,只能装整数,很大很大很大
2.1)长整型直接量需在数字后加L或l(L较好,写在第一个)
2.2)运算时若有可能溢出,建议在第1个数字后加L
2.3)System.currentTimeMillis()用于获取自1970.1.1零时到此时此刻的毫秒数
3)double:浮点型,8个字节,只能装小数,很大很大很大
3.1)浮点数直接量默认为double型,表示float需在数字后加F或f
3.2)double和float型数据参与运算时,有可能出现舍入误差
//二进制无法精确表示0.1,财务ERP:BigDecimal
4)boolean:布尔型,1个字节,只能取值为true和false
5)char:字符型,2个字节
5.1)采用Unicode字符集编码,每个字符对应一个码。表现的形式是字符char,本质上是码int(0到65535之间)
ASCII码: 'a'--97 'A'--65 '0'--48
5.2)字符直接量需放在单引号中,只能有一个
5.3)特殊符号需通过\来转义
5.基本数据类型间的转换:
数据类型从小到大依次为:byte,short,int,long,float,double
char
1)两种方式:
1.1)自动类型转换:小类型到大类型
1.2)强制类型转换:大类型到小类型
(要转换成为的数据类型)变量 强转有可能溢出或丢失精度
2)两点规则:
2.1)整数直接量可以直接赋值给byte,short,char,但不能超出范围 2.2)byte、short、char型数据参与运算时,先一律转换为int再运算
byte b1=5;byte b2=6;
byte b3=(byte)(b1+b2);
6.Scanner的用法:
1)在package下: import java.util.Scanner;
2)在main中: Scanner scan = new Scanner(System.in);
3)在第2步之后:
System.out.println("请输入年龄:"); //提示
int age = scan.nextInt();
System.out.println("请输入价格:");
double price = scan.nextDouble();
7.运算符:
1)算术运算符:+,-,*,/,%,++,--
2)关系运算符(一个条件控制):>,<,>=,<=,==,!=
//结果为boolean型,算数运算符优先于关系运算符
3)逻辑运算符(多个条件控制):
&&(短路与):见false则false
||(短路或):见true则true
! :优先级最高
结果为boolean型,逻辑运算建立在关系运算之上
逻辑短路(后面的不走):&&若第一个为false,则false,||若第一个为true,则true
4)赋值运算符:=,+=,-=,*=,/=,%=
赋值语句本身的值为所赋的值 a=b=3;
面试题:short s=5; s+=10;(对)//自带强转功能 s=s+10;(错)
5)字符串连接运算符(若两边出现字符串):+ //String System.out.println("age="+age);
6)三目/条件运算符:
boolean?数1:数2
int max=a>b?a:b(输出a,b中的较大值)
//a,b也可以是字符串
三目的嵌套
8.分支结构:
有条件的执行某语句,并非每句必走
1)if结构:1条路,满足就执行,不满足不执行
if(){
}
2)if...else结构:2条路,满足就执行,不满足执行另一件事
if(){}else{}
3)if...else if结构:多条路
if(){}else if(){}else if(){}else{}//最后一个else{}可以没有
循环的嵌套越少越好
4)switch...case结构:多条路
switch(整型表达式)
//byte,short,int,char可作为switch中的量,而long不行
{case 整型常量1:
执行语句;
break;
......
}
优点:效率高、结构清晰
缺点:整数、相等
break:跳出switch(增加合理性)
default:放在最下面不用写break,所有case未匹配才会进入
9.循环:
反复执行一段相同或相似的代码
10.循环三要素:
1)循环变量的初始化
2)循环的条件(以循环变量为基础) //避免死循环:条件一直为真
3)循环变量的改变(向着循环的结束变)
//循环变量:在整个循环过程中反复改变的那个数
11.循环结构:
1)while结构:(当...)
while(boolean){//多次判断,多次执行
循环体;
}
先判断后执行,有可能一次都不执行
循环结束:条件为假或遇见break
2)do...while结构:(直到...)
do{
循环体;
}while(boolean);
先执行后判断,至少执行一次要素1与要素3相同时,首选do...while
eg.scan.nextInt();
3)for:
for (int i = 0; i < args.length; i++) {
循环体;
}
1,3位置可多个
应用率最高,固定次数循环
12.break和continue
break(用于循环和switch中):跳出循环
break配合if使用,实现在某种条件下提前退出循环
if(answer==-1){//answer为一个正常运算不会产生的值
break;}
continue(只用于循环中)(鸡肋):跳过循环体中剩余语句而进入下一次循环
13.三种循环的更佳适用情况:
1)while:"当..."
2)do...while:"直到..."---要素1与要素3相同
3)for:固定次数循环
14.嵌套循环:
1)循环中套循环,一般多行多列时使用,外层控制行,内层控制列
2)执行过程:外层循环走一次,内层循环走所有次
3)建议:循环层次越少越好,能用一层就不用两层,能用两层就不用三层。若业务必须通过三层循环以上的循环来解决,说明设计有问题 4)break只能跳出一层循环
15.程序=算法+数据结构
1)算法:解决问题的流程/步骤(顺序、分支、循环)
2)数据结构:将数据按照某种特定的结构来保存
//设计良好的/合理的数据结构会导致好的算法
16.数组:
1)是一种数据类型(引用类型)
2)相同数据类型元素的集合
3)数组的定义: int[] arr = new int[10];
4)数组的初始化:
int[] arr = new int[4]; //0,0,0,0
int[] arr = {1,4,5,8}; //1,4,5,8
int[] arr = new int[]{1,4,5,8}; //1,4,5,8
int[] arr; arr = {1,4,5,8}; //编译错误
arr = new int[]{1,4,5,8}; //正确
5)数组的访问:
5.1)通过(数组名.length)可以获取数组的长度(元素的个数)
int[] arr = new int[4]; System.out.println(arr.length); //4
5.2)通过下标/索引来访问数组中的元素:下标从0开始,最大到(数组的长度-1)
int[] arr = new int[3];
arr[0] = 100; //给第1个元素赋值为100
arr[3] = 400; //数组下标越界异常(不是编译错误,是运行错误)
System.out.println(arr[arr.length-1]); //输出最后一个元素
6)数组的遍历:
int[] arr = new int[10];
for(int i=0;i<arr.length;i++){ //遍历随机赋值
arr[i] = (int)(Math.random()*100);}
for(int i=0;i<arr.length;i++){ //遍历输出
System.out.println(arr[i]); }
for(int i=arr.length-1;i>=0;i--){//遍历反向输出
System.out.println(arr[i]); }
- 数组的复制:
7.1)System.arraycopy(a,1,a1,0,4);
7.2)int[] a1 = Arrays.copyOf(a,6);
a = Arrays.copyOf(a,a.length+1); //扩容
8)数组的排序:
8.1)Arrays.sort(arr); //升序
8.2)冒泡排序(效率中等)://编码题(面试重点)
5个数冒4轮,每一轮都是从第1个元素开始冒,冒出来的就不再参与比较了。
int[]arr={87,23,45,1};
for (int i = 0; i < a.length-1; i++){ //i控制轮数
for (int j = 0; j < a.length-1-i; j++){ //j控制下标
if (a[j]>a[j+1]){
int t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } }//追尾绕圈
17.方法:函数、过程
1)封装一段特定的业务逻辑功能
2)方法尽可能独立,只干一件事
3)方法可以被反复调用多次
4)减少代码重复,有利于代码维护,有利于团队协作
18.方法的定义:
修饰词 返回值类型 方法名(参数列表){ 方法体 }
有参可以使方法更灵活
19.方法的调用:
1)无返回值:方法名(有参传参);//不需要用到方法中的数据
eg.System.out.println();
Array.sort(arr);//类型写为void
2)有返回值: 数据类型 变量 = 方法名(有参传参);
eg.int a=scan.nextInt();
20.return:
1)return 值;
结束方法的执行,返回结果给调用方 --------有返回值的方法中
2)return;
结束方法的执行 -------无返回值的方法中
21.猜字符游戏:
变量、数据类型、运算符、 分支结构、循环结构、数组、方法
猜字符游戏的目的:
- 了解一个软件开发的大致步骤
2)对语言基础知识做总结运用、掌握一些小算法
猜字符游戏:
- 设计数据结构:变量
1)char[] chs; //随机字符数组
2)char[] input; //用户输入的字符数组
3)int[] result; //对比结果
4)int score; //得分
2.设计程序结构:方法
1)主方法:
public static void main(String[] args){ //... }
2)生成随机字符数组chs:
public static char[] generate(){ char[] chs = new char[5]; //... return chs; }
3)对比:随机字符数组chs与用户输入的字符数组input public static int[] check(char[] chs,char[] input){ int[] result = new int[2]; //... return result; }
3.设计算法:方法体 String str = "abc";
1)将字符串转换为字符数组:
char[] input = str.toCharArray();
- 将字符串转换为大写字母: str = str.toUpperCase();
将字符串转换为小写字母: str = str.toLowerCase();
3)判断字符串内容相等: if(str.equals("abc")){ }
基本数据类型判断相等-----用==
String类型判断内容相等------------用equals()
exit时退出
1)手里面藏个数chs2)猜吧!接收用户输入的数input3)对比chs与input,得到对比结果: 3.1)猜对了,算分结束 3.2)猜错了,重复第2步
while(true){ //自造死循环 适当情况下break ... ...}
Math.random()------------0.0到0.99999999999999999...
面向对象
1.类和对象
1)现实世界是由很多对象组成的,基于对象抽出了类
2)对象:真实存在的单个的个体 类:类型/类别,代表一类个体
3)类中可以包含:
所有对象所共有的属性/特征------------成员变量
所有对象所共有的行为-----------------方法
4)一个类可以创建多个对象,同一类型所创建的对象,结构相同,数据不同
5)类是对象的模板,对象是类的具体的实例
2.如何创建类,对象以及访问成员
class Emp{ //Emp就是自己创建的一个数据类型--雇员类 String name;
int age;
double salary;
void print(){
System.out.println("姓名:"+name);
System.out.println("年龄:"+age);
System.out.println("工资:"+salary); }}
class Test{ //测试类
public static void main(String[] args){
Emp e = new Emp(); //创建了Emp的对象
e.name = "zhangsan";
e.age = 25;
e.salary = 5000.0;
e.print(); } }
结构化设计的弊端:1)缺乏对数据的封装2)数据和方法的分离
高质量的代码: 复用性好、扩展性好、维护性好、 可移植性好、健壮性好、可读性好、效率高。
3.方法的签名:方法名+参数列表
4.方法的重载(Overload):
1)发生在一个类中,方法名称相同,参数列表不同,方法体不同
2)编译器在编译时会根据方法的签名自动绑定调用的方法
5.构造方法:构造函数、构造器,构建器
1)给成员变量赋初值
2)与类同名,没有返回值类型(去掉void)
3)在创建对象(new)时自动调用构造方法
/*1)创建了一个学生对象
2)给成员变量赋默认值
3)调用构造方法Student zs = new Student();*/
小括号是方法的标志
4)若自己不写构造方法,则编译器默认一个无参构造方法。若自己写了构造方法,则不再默认提供
5)构造方法可以重载,构造方法多意味着给用户初始化方式的选择较多
6.this:
指代当前对象,哪个对象调用方法它指的就是哪个对象。只能用在方法中,方法中访问成员变量之前默认有个this
this的用法:
1)this.成员变量名------访问成员变量
class Student{
String name; //成员变量
int age;
String address;
Student(String name,int age,String address){ //局部变量 this.name = name;//把局部变量的值赋给成员变量
this.age = age;
this.address = address;
}
}
成员变量和局部变量可以同名------用的时候采用就近原则
成员变量与局部变量同名时,this不能省略
2)this.方法名()--------------调用方法(一般不用) 3)this()---------------------调用构造方法
//写多个构造方法时,通过在一个构造方法中调用最完整的构造方法来减少重复
Student(String name){
this(name,0,null); }
Student(String name,int age){
this(name,age,null); }
Student(String name,int age,String address){
this.name = name; this.age = age; this.address = address; }}
7.null:空,没有指向任何对象
若引用的值为null,则该引用不能再进行任何操作了。若操作则发生NullPointerException空指针异常
8.引用类型变量画等号:
/*内存管理:由JVM管理的
- 堆:new出来的对象(包括成员变量)
- 栈:局部变量(包括方法的参数)
3)方法区:.class字节码文件(包括方法)*/
1)引用类型变量画等号:指向同一个对象,通过一个引用对数据的修改会影响另一个引用对数据的访问
2)基本类型变量画等号:
1)赋值 2)对一个变量的修改不会影响另一个变量
9.引用类型数组:
1)Student[] stus = new Student[3];
stus[0] = new Student("zhangsan",25,"LF");
stus[1] = new Student("lisi",26,"JMS");
stus[2] = new Student("wangwu",28,"SD");
stus[1].age = 36;
System.out.println(stus[0].name);
stus[2].sayHi();
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; //给arr第2个元素中的第1个元素赋值为100
4)int[][]arr = new int[3][4]; //3行4列--数组的数组
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
arr[i][j] = (int)(Math.random()*100); } }
10.继承:
1)作用:代码复用
2)通过extends来实现继承
3)超类/父类:所有派生类所共有的属性和行为
派生类/子类:派生类所特有的属性和行为
4)派生类继承超类后,派生类具有:派生类的+超类的
5)一个超类可以有多个派生类,一个派生类只能有一个超类--单一继承
6)具有传递性
7)java规定:构造派生类之前必须先构造超类,在派生类的构造方法中若自己不调用超类的构造方法则默认super()调用超类的无参构造方法。在派生类的构造方法中若自己调用了超类的构造方法 则不再默认提供。super()调用超类构造方法,必须位于派生类构造的第一行
11.super:指代当前对象的超类对象
super的用法:
- super.成员变量名------访问超类的成员变量
2)super.方法名()--------调用超类的方法
3)super()-----------调用超类的构造方法
11.向上造型:
1)超类型的引用指向派生类的对象
2)能点出来什么,看引用的类型
Person p1 = new Student();
Person p2 = new Teacher();
Person p3 = new Doctor();
p1.只能点出来Person的p2.只能点出来Person的p3.只能点出来Person的
Animal o1 = new Tiger(); //向上造型
Animal o2 = new Dog();
Animal o3 = new Cat();
o1到o3.只能点出来Animal的
//动物是动物
Animal o1 = new Animal();
//老虎是老虎
Tiger o2 = new Tiger();
//老虎是动物
Animal o3 = new Tiger();
//动物是老虎---语义不通
Tiger o4 = new Animal(); //编译错误
class Animal{ //动物类}
class Tiger extends Animal{ //老虎类}
继承要符合is a(是一个)的关系
12.方法的重写(Override):重新写、覆盖
1)发生在父子类中,方法名相同,参数列表相同,方法体不同
2)重写方法被调用时,看对象的类型
继承了一个中餐馆
A:我还是想做中餐----不需要重写
B:我想改做西餐-----需要重写
C:我想在中餐之上加入西餐-----需要重写(super中餐,再加西餐)
3)遵循"两同两小一大"原则:
3.1)两同:方法名称相同,参数列表相同
3.2)两小:
3.2.1)派生类方法的返回值类型小于或等于超类方法的
1)void时,必须相等
2)基本类型时,必须相等
3)引用类型时,小于或等于
3.2.2)派生类方法抛出的异常小于或等于超类方法的---API时讲
3.3)一大: 派生类方法的访问权限大于或等于超类方法的
13.重写与重载的区别:(常见面试题)
1)重写(Override):
1.1)发生在父子类中,方法名相同,参数列表相同,方法体不同
1.2)遵循"运行期绑定",看对象类型来调用方法
2)重载(Overload):
2.1)发生在一个类中,方法名相同,参数列表不同,方法体不同
2.2)遵循"编译期绑定",看引用/参数类型来绑定方法
class Aoo{ void show(){ }}
class Boo extends Aoo{ void show(String name){ //重载 }}
Boo o = new Boo();
o.show();
o.show("zhangsan");
swing相关:--不需要掌握1)JFrame:窗口(相框)2)JPanel:面板(相板)
C/S:客户端/服务器B/S:浏览器/服务器-----你们所参与的
HTML
java----跨平台、开源免费.net(C#)--不能跨平台、非开源收费
14.package:
1)作用:避免类的命名冲突
2)包名可以有层次结构,同包中的类不能同名
3)类的全称:包名.类点
4)建议:包名所有字母都小写
import:
1)同包中的类可以直接访问,不同包中的类不能直接访问,想访问有如下两种方式:
1.1)先import声明类再使用类----建议
1.2)类的全称------------------太繁琐
15.访问控制修饰符:
1)public:公共的,任何类 2)protected:受保护的,本类、派生类、同包类 3)默认的:什么也不写,本类、同包类 4)private:私有的,本类 说明: 1)类的访问修饰符只能是public和默认的 2)类中成员的访问修饰符如上4种都可以
16.final:
最终的、不可改变的---------单独应用率低 1)修饰变量:变量不能被改变 2)修饰方法:方法不能被重写 3)修饰类:类不能被继承
17.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)何时用:加载/初始化静态资源(图片、音频、视频等)
读图片-------------文件的IO操作(特别容易异常的)-------------------java强制必须做异常处理
class Hero{ width,height,x,y,life,doubleFire,图片}
Arrays.sort(arr);
假设sort()不是静态的: 无论是a1,a2,a3,...,a100中的哪一个对象 去sort(arr),最终的结果都是一样的 说明:sort()的操作仅与参数相关而与对象无关
Arrays a1 = new Arrays();
a1.sort(arr);
Arrays a2 = new Arrays();
a2.sort(arr);
Arrays a3 = new Arrays();
a3.sort(arr);
double d = Math.sqrt(25); //静态方法
假设sqrt()不是静态的: 无论m1,m2,m3,...,m100中的哪一个对象 去sqrt(25),最终的结果都是一样的 说明:sqrt()的操作仅与参数相关而与对象无关
Math m1 = new Math(); double d = m1.sqrt(25); //5.0
Math m2 = new Math(); double d = m2.sqrt(25); //5.0
Math m3 = new Math(); double d = m3.sqrt(25); //5.0
Scanner scan = new Scanner(System.in);int a = scan.nextInt();double b = scan.nextDouble(); //实例方法
double c = Math.random();double d = Math.sqrt(25);Arrays.sort(arr); //静态方法
实例变量多还是静态变量多?----------------实例变量多实例方法多还是静态方法多?----------------实例方法多
地图-------------------map.png(一份)百度音乐---------------意外.mp3(一份)爱奇艺-----------------吸血鬼日记第8季第1集.avi(一份)
1)堆:new出来的对象(包括实例变量)2)栈:局部变量(包括方法的参数)3)方法区:.class字节码文件(包括方法、静态变量)
成员变量:1)实例变量:没有static修饰的,属于对象的,存储在堆中, 有几个对象就有几份, 通过对象点来访问2)静态变量:有static修饰的,属于类的,存储在方法区中, 只有一份, 通过类名点来访问
class Aoo{ int a; //实例变量 static int b; //静态变量}
方法: public变量: 1)超类中的--------protected 2)派生类中的------private
数据(变量)私有化(private),行为(方法)公开化(public)
class Card{ private String cardId; private String cardPwd; private double balance;
public boolean checkPwd(String pwd){ //检测密码 if(cardPwd.equals(pwd)){ return true; }else{ return false; } } public boolean payMoney(double money){ //支付金额 if(balance>=money){ balance-=money; return true; }else{ return false; } }}
package java.util;class Scanner{ Scanner(Stream s){ } int nextInt(){ } double nextDouble(){ }}
import java.util.Scanner;Scanner scan = new Scanner(System.in);int a = scan.nextInt();double b = scan.nextDouble();
A公司: package a.b.c.d; class Aoo{ }B公司: package a.b.c.d; class Aoo{ }
建议: 域名反写 . 项目名称 . 模块名称 . 类名 cn.tedu . aproject . stumanager . cn.tedu . aproject . teachmanager .
cn.tedu . bproject
com.taobao . com.jd .
package a.b.c.d;class Aoo{ //a.Aoo}
package b.m.y.u.n;class Aoo{ //b.Aoo}
Shoot射击游戏第一天:1.创建6个对象类,并创建World类测试
Shoot射击游戏第二天:1.给6个对象类添加构造方法,并测试
Shoot射击游戏第三天:1.设计小敌机数组、大敌机数组、小蜜蜂数组、子弹数组,并测试2.设计FlyingObject超类,6个对象类继承3.给FlyingObject类设计两个构造方法,6个对象类分别调用
Shoot射击游戏第四天:1.将小敌机数组、大敌机数组、小蜜蜂数组合为FlyingObject数组,并测试2.在6个对象类中重写超类的step()3.画窗口
Shoot射击游戏第五天:1.给类中成员添加访问控制修饰符2.给6个对象类添加图片属性
Shoot射击游戏第六天:1.设计窗口的宽和高为常量,适当地方做修改2.画对象: 1)想画对象需要获取对象的图片,每个对象都得获取图片, 意味着获取图片为共有行为,所以设计在超类FlyingObject中, 每个对象获取图片的行为是不同的,所以设计为抽象方法 ----在FlyingObject中设计抽象方法getImage()获取对象的图片 2)获取图片时需要考虑对象的状态,因为不同状态下获取的图片是不同的, 每个对象都有状态,所以将状态设计在超类中,一般为常量 对象状态分三种:活着的、死了的、删除的 ----FlyingObject中设计LIFE、DEAD、REMOVE常量,state表示当前状态 获取图片时需在判断对象的状态,而每个对象都能判断状态, 所以判断状态行为为共有行为,设计在FlyingObject超类中, 每个对象判断状态的行为都一样,所以设计为普通方法 ----FlyingObject中设计isLife()、isDead()、isRemove() 3)在6个派生类中重写抽象方法getImage()获取图片 3.1)天空Sky,直接返回image 3.2)子弹Bullet: 3.2.1)若活着的,返回image 3.2.2)若死了的,改为删除状态 3.3)英雄机Hero: 3.3.1)若活着的,返回images[0]和images[1]来回切换 3.4)小敌机Airplane: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 3.5)大敌机BigAirplane: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 3.6)小蜜蜂Bee: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 4)获取了图片,则可以开始画对象了,每个对象都能画,为共有行为 因为每个对象画图片的行为都是一样的,所以设计为普通方法 ----在FlyingObject中设计普通方法paintObject()实现画对象 5)天空需要画两张图片,所以在天空Sky中重写paintObject() ----在Sky中重写paintObject()画两张图片 6)画对象行为写好后,在窗口上调用即可 ----在World中重写paint()
步骤:1.获取图片(1+2+3)2.画对象(4+5)3.窗口调用(6)
18.static final常量:
1)必须声明同时初始化 2)类名点来访问,不能被改变 3)建议:常量名所有字母都大写,多个单词由_分隔 4)编译器在编译时将常量直接替换为具体的值,效率高 5)何时用:数据永远不变,并且经常使用
19.抽象方法:
1)由abstract修饰 2)只有方法的定义,没有具体的实现(连{}都没有)
20.抽象类:
1)由abstract修饰 2)包含抽象方法的类必须是抽象类 不包含抽象方法的类也可以声明为抽象类------我乐意 3)抽象类不能被实例化 4)抽象类是需要被继承的,派生类: 4.1)重写所有抽象方法-----------变不完整为完整 4.2)也声明为抽象类-------------一般不这么做 5)抽象类的意义: 5.1)封装派生类共有的属性和行为------------代码复用 5.2)为所有派生类提供统一的类型------------向上造型 5.3)可以包含抽象方法,为所有派生类提供统一的入口, 派生类的具体行为不同,但入口是一致的
设计规则:1)将派生类所共有的属性和行为,抽到超类中--------抽共性2)所有派生类的行为都一样,设计为普通方法 所有派生类的行为都不一样,设计为抽象方法3)
abstract class Aoo{ //不能被实例化 void show(){...} void say(){...}}
FlyingObject o2 = new Airplane();FlyingObject o4 = new BigAirplane();FlyingObject o3 = new Bee();
FlyingObject[] enemies = new FlyingObject[3];enemies[0] = new Airplane();enemies[1] = new BigAirplane();enemies[2] = new Bee();for(int i=0;i<enemies.length;i++){ enemies[i].step(); //最终走的是小敌机、大敌机、小蜜蜂的}
abstract class FlyingObject{ width,height,x,y BufferedImage getImage(){...} //读取图片 abstract void step(); //飞行物移动}class Airplane extends FlyingObject{ void step(){ //重写抽象方法 y坐标改变 }}class Bee extends FlyingObject{ void step(){ //重写抽象方法 x和y坐标改变 }}
new FlyingObject(); //编译错误
abstract class FlyingObject{ width,height,x,y BufferedImage getImage(){...} abstract void step();}class Airplane extends FlyingObject{ void step(){ y坐标改变 }}class Bee extends FlyingObject{ void step(){ x和y坐标改变 }}
FlyingObject o = new FlyingObject(); //错误FlyingObject[] oo = new FlyingObject[3]; //正确
new FlyingObject(); //编译错误new FlyingObject[3]; //正确---FlyingObject数组对象FlyingObject f; //正确
NAMESTUDENT_NAME
Shoot射击游戏第七天:1.敌人入场: 1)敌人是由窗口产生的,所以在World类中设计nextOne()生成敌人 2)敌人入场是定时发生的,所以在run中调用enterAction()实现敌人入场 在enterAction()中: 每400毫秒获取敌人对象,enemies扩容,装到最后一个元素上2.子弹入场: 1)子弹是由英雄机发射出来的,所以在Hero类中设计shoot()生成子弹对象 2)子弹入场是定时发生的,所以在run中调用shootAction()实现子弹入场 在shootAction()中: 每300毫秒获取子弹对象,bullets扩容,数组的追加3.飞行物移动: 1)飞行物移动为共有行为,所以在FlyingObject中设计抽象方法step() 派生类中重写step() 2)飞行物移动是定时发生的,所以在run中调用stepAction()实现飞行物移动 在stepAction()中: 天空动,遍历敌人敌人动,遍历子弹子弹动
Shoot射击游戏第一天:1.创建6个对象类,并创建World类测试
Shoot射击游戏第二天:1.给6个对象类添加构造方法,并测试
Shoot射击游戏第三天:1.设计小敌机数组、大敌机数组、小蜜蜂数组、子弹数组,并测试2.设计FlyingObject超类,6个对象类继承3.给FlyingObject类设计两个构造方法,6个对象类分别调用
Shoot射击游戏第四天:1.将小敌机数组、大敌机数组、小蜜蜂数组合为FlyingObject数组,并测试2.在6个对象类中重写超类的step()3.画窗口
Shoot射击游戏第五天:1.给类中成员添加访问控制修饰符2.给6个对象类添加图片属性
Shoot射击游戏第六天:1.设计窗口的宽和高为常量,适当地方做修改2.画对象: 1)想画对象需要获取对象的图片,每个对象都得获取图片, 意味着获取图片为共有行为,所以设计在超类FlyingObject中, 每个对象获取图片的行为是不同的,所以设计为抽象方法 ----在FlyingObject中设计抽象方法getImage()获取对象的图片 2)获取图片时需要考虑对象的状态,因为不同状态下获取的图片是不同的, 每个对象都有状态,所以将状态设计在超类中,一般为常量 对象状态分三种:活着的、死了的、删除的 ----FlyingObject中设计LIFE、DEAD、REMOVE常量,state表示当前状态 获取图片时需在判断对象的状态,而每个对象都能判断状态, 所以判断状态行为为共有行为,设计在FlyingObject超类中, 每个对象判断状态的行为都一样,所以设计为普通方法 ----FlyingObject中设计isLife()、isDead()、isRemove() 3)在6个派生类中重写抽象方法getImage()获取图片 3.1)天空Sky,直接返回image 3.2)子弹Bullet: 3.2.1)若活着的,返回image 3.2.2)若死了的,改为删除状态 3.3)英雄机Hero: 3.3.1)若活着的,返回images[0]和images[1]来回切换 3.4)小敌机Airplane: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 3.5)大敌机BigAirplane: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 3.6)小蜜蜂Bee: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 4)获取了图片,则可以开始画对象了,每个对象都能画,为共有行为 因为每个对象画图片的行为都是一样的,所以设计为普通方法 ----在FlyingObject中设计普通方法paintObject()实现画对象 5)天空需要画两张图片,所以在天空Sky中重写paintObject() ----在Sky中重写paintObject()画两张图片 6)画对象行为写好后,在窗口上调用即可 ----在World中重写paint()
21.成员内部类:应用率不高、了解
1)类中套类,外面的称为Outer外部类,里面的称为Inner内部类 2)内部类通常只服务于外部类,对外不具备可见性 3)内部类对象通常是在外部类中创建的 4)内部类中可以直接访问外部类的成员(包括私有的) 内部类中有个隐式的引用指向了创建它的外部类对象 eg: 外部类名.this
22.匿名内部类:
1)若想创建一个类(派生类)的对象,并且对象只被创建一次, 此时该类不必命名,称为匿名内部类 2)jdk1.7(含)之前,想访问匿名内部类外面的变量, 该变量必须是final的
小面试题:问:匿名内部类有独立的.class吗?答:有
功能:1)先写行为: 1.1)对象所特有的行为,设计在对应的对象类中 1.2)所有对象都具有的行为,设计在超类中2)窗口调用: 2.1)定时触发的,设计在定时器中调用 2.2)事件触发的,设计在侦听器中调用
异常------------找问题(什么原因导致的异常)程序的运行结果与你们预期的结果不同----如何解决?1)打桩:System.out.println(数据);2)Debug调试工具:--------------------周五讲
paint()的调用方式:--------------不需要掌握1)frame.setVisible(true);2)repaint();
来一个敌人,给enemies扩一个容,将敌人装到最后一个元素上
假设enemies中有5个敌人来一个敌人,
5+1--------------(加1)5+(-1)-----------(减1)
敌人入场-----------------是由窗口产生的(World类中)子弹入场-----------------是由英雄机发射的(Hero类中)飞行物移动---------------共有行为(FlyingObject类中)
Bullet[] bs = hero.shoot(); //获取子弹对象bullets = Arrays.copyOf(bullets,bullets.length+bs.length); //扩容(bs有几个元素就扩大几个容量)System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length); //数组的追加
if(bs.length>2){ //三 bullets[bullets.length-1] = bs[0]; bullets[bullets.length-2] = bs[1]; bullets[bullets.length-3] = bs[2];}else if(bs.length>1){ //双 bullets[bullets.length-1] = bs[0]; bullets[bullets.length-2] = bs[1];}else{ //单 bullets[bullets.length-1] = bs[0];}
//英雄机发射子弹(生成子弹对象)public Bullet[] shoot() {
}
//生成敌人对象public FlyingObject nextOne(){}
//窗口class World extends JPanel{ //生成敌人(小敌机、大敌机、小蜜蜂)对象 public FlyingObject nextOne(){ Random rand = new Random(); int type = rand.nextInt(20); //0到19 if(type<5){ //0到4,返小蜜蜂 return new Bee(); }else if(type<16){ //5到15,返小敌机 return new Airplane(); }else{ //16到19,返大敌机 return new BigAirplane(); } }
//生成敌人(小敌机、大敌机、小蜜蜂)对象 public FlyingObject nextOne(){ Random rand = new Random(); int type = rand.nextInt(3); //0到2 if(type==0){ return new Bee(); }else if(type==1){ return new Airplane(); }else{ return new BigAirplane(); } }
}
1)敌人入场--------------------定时发生2)子弹入场--------------------定时发生3)飞行物移动------------------定时发生
TimerTask,long,long
timer.schedule(new TimerTask(){ public void run(){ //定时干的那个事--每10毫秒走一次 }},10, 10);
Student,int
a.show(new Student(),25);
第一个10:从程序启动开始到第一次触发的时间时隔
第二个10:从第一次触发到第二次触发的时间间隔 从第二次触发到第三次触发的时间间隔 从第三次触发到第四次触发的时间间隔 ...
定时器---------定时自动发生
Mama$Baby.classNstInnerClassDemo$1.classNstInnerClassDemo$2.classNstInnerClassDemo$3.class
字母、数字、_和$
Aoo o1 = new Aoo(); //正确Boo o2 = new Boo(); //编译错误
class Aoo{ private int a; void show(){ Boo o1 = new Boo(); //正确 } class Boo{ void test(){ System.out.println(a); System.out.println(Aoo.this.a); System.out.println(this.a); //编译错误 } }}
功能:1)敌人入场2)子弹入场3)飞行物移动
Shoot射击游戏第八天:1.英雄机随着鼠标移动: 1)英雄机随着鼠标动为英雄机的行为,在Hero中设计moveTo()实现英雄机移动 2)英雄机随着鼠标动为事件触发的,所以在侦听器重写mouseMoved()鼠标移动事件 在mouseMoved()中: 获取鼠标的x和y坐标,英雄机动2.删除越界的敌人和子弹: 1)在FlyingObject中设计outOfBounds()检测敌人是否越界 在Bullet中重写outOfBounds()检测子弹是否越界 2)删除越界为定时发生的,所以在run()中调用outOfBoundsAction()实现删除越界敌人和子弹 在outOfBoundsAction中: 声明不越界敌人/子弹数组,遍历敌人/子弹数组,获取对象, 判断若对象不越界,则将对象添加到不越界敌人/子弹数组中 最后将不越界敌人/子弹数组,复制到enemies/bullets中3.设计Enemy得分接口,Airplane和BigAirplane实现Enemy接口 设计Award奖励接口,Bee实现Award接口
23.接口:
1)是一种数据类型(引用类型) 2)由interface定义 3)只能包含常量和抽象方法 4)不能被实例化 5)接口是需要被实现/继承的,实现类/派生类: 必须重写接口中的所有抽象方法 6)一个类可以实现多个接口,用逗号分隔 若又继承又实现时,应先继承后实现 7)接口可以继承接口(多个)
设计规则:1)将所有派生类所共有的属性和行为,抽到超类中--------抽共性2)派生类的行为都一样,设计为普通方法 派生类的行为不一样,设计为抽象方法3)将部分派生类所共有的行为,抽到接口中 符合既是也是的关系时,使用接口 接口是对继承的单根性的扩展----------实现多继承
接口的好处-----------明天下午讲
interface Inter1{ void show();}interface Inter2{ void test();}interface Inter3 extends Inter1,Inter2{ void say();}
子弹打掉小敌机---------------玩家得1分子弹打掉大敌机---------------玩家得3分
子弹打掉小蜜蜂----------------英雄机得奖励子弹打掉大黄蜂----------------英雄机得奖励、玩家得5分
class FlyingObject{ width,height,x,y abstract void step(); //移动 BufferedImage loadImage(){...} //读图片 abstract BufferedImage getImage(); //获取图片 void paintObject(){...} //画对象}interface Enemy{ //得分接口 int getScore();}interface Award{ //奖励接口 int getAwardType();}
class Bee extends FlyingObject implements Award{ public int getAwardType(){}}class BigYellowBee extends FlyingObject implements Award,Enemy{ public int getAwardType(){} public int getScore(){ return 5; }}
class Airplane extends FlyingObject implements Enemy{ public int getScore(){ return 1; }}class BigAirplane extends FlyingObject implements Enemy{ public int getScore(){ return 3; }}
class Bullet extends FlyingObject{}class Hero extends FlyingObject{}class Sky extends FlyingObject{}
接口是完全抽象的抽象类
Aoo o1 = new Aoo();Inter2 o2 = new Aoo(); //向上造型(造型为直接父类)Inter1 o3 = new Aoo(); //向上造型(造型为间接父类)
interface Inter1{ void show();}interface Inter2 extends Inter1{ void test();}class Aoo implements Inter2{ public void test(){} public void show(){}}
类和类---------------extends接口和接口-----------extends类和接口-------------implements
interface Inter1{ void show();}interface Inter2{ void test();}abstract class Aoo{ abstract void say();}class Boo extends Aoo implements Inter1,Inter2{ public void show(){} public void test(){} void say(){}}
interface Inter1{ void show(); void test();}class Aoo implements Inter1{ public void show(){} public void test(){}}
interface Inter1{ public static final int NUM = 5; public abstract void show(); int COUNT = 5; //默认public static final void say(); //默认public abstract
int number; //编译错误,常量必须声明同时初始化 void test(){} //编译错误,抽象方法不能有方法体}
interface Inter1{}abstract class Aoo{}
面向过程编程---------以方法为单位面向对象编程---------以类/对象为单位----面向接口编程---------以接口为单位
设计规则:1)2)3)
功能:1)英雄机随着鼠标移动2)删除越界的敌人和子弹3)设计两个接口
//删除越界的敌人和子弹 */public void outOfBoundsAction() { int index = 0; //1)下标 2)不越界敌人个数 FlyingObject[] enemyLives = new FlyingObject[enemies.length]; //不越界敌人数组 for(int i=0;i<enemies.length;i++){ //糖都找好了 FlyingObject f = enemies[i]; if(!f.outOfBounds()){ //不越界 enemyLives[index] = f; index++; } } enemies = Arrays.copyOf(enemyLives,index);}
//删除越界的敌人和子弹 */public void outOfBoundsAction() { //10毫秒走一次 //假设有50个敌人,其中有30个越界了,意味着缩容30次 //效率低(类似:找一块糖邮一次,找一块糖邮一次) for(int i=0;i<enemies.length;i++){ FlyingObject f = enemies[i]; if(f.outOfBounds()){ //越界了 将f从enemies数组中删除(缩容) } }}
swing相关的事件触发:--------------了解1)事件:发生了一个事2)事件处理:发生事之后所做的操作3)侦听器: 3.1)有一个侦听器对象 3.2)把侦听器装到面板去
MouseAdapter l = new MouseAdapter(){ //重写mouseMoved()鼠标移动 public void mouseMoved(MouseEvent e){ }};this.addMouseListener(l);this.addMouseMotionListener(l);
class FlyingObject{ public boolean outOfBounds(){ y向上出窗口越界 }}class Airplane extends FlyingObject{}class BigAirplane extends FlyingObject{}class Bee extends FlyingObject{}class Bullet extends FlyingObject{ 重写outOfBounds()-----y向上出窗口越界}class Hero extends FlyingObject{}class Sky extends FlyingObject{}
class Aoo extends MouseAdapter{}
事件 事件处理鼠标点击 启动状态变为运行状态鼠标移动 英雄机随着动鼠标移出 运行状态变为暂停状态鼠标移入 暂停状态变为运行状态
10毫秒----1秒钟要走100次
10个和100个
Shoot射击游戏第九天:1.子弹与敌人的碰撞: 1)在FlyingObject中设计hit()实现检测碰撞 在FlyingObject中设计goDead()实现飞行物去死 在Hero中设计addLife()增命、addDoubleFire()增火力 2)碰撞为定时发生的,所以在run()中调bulletBangAction()实现子弹与敌人的碰撞 在bulletBangAction()中: 遍历子弹得子弹,遍历敌人得敌人,判断是否撞上了, 若撞上了: 子弹去死、敌人去死 判断被撞对象: 若能得分,得getScore()玩家增分 若是奖励,则getAwardType()英雄机奖励(命、火力值)2.画分和画命: 1)在Hero中设计getLife()获取英雄机的命数 2)在paint()中: 画分和画命
Shoot射击游戏第一天:1.创建6个对象类,并创建World类测试
Shoot射击游戏第二天:1.给6个对象类添加构造方法,并测试
Shoot射击游戏第三天:1.设计小敌机数组、大敌机数组、小蜜蜂数组、子弹数组,并测试2.设计FlyingObject超类,6个对象类继承3.给FlyingObject类设计两个构造方法,6个对象类分别调用
Shoot射击游戏第四天:1.将小敌机数组、大敌机数组、小蜜蜂数组合为FlyingObject数组,并测试2.在6个对象类中重写超类的step()3.画窗口
Shoot射击游戏第五天:1.给类中成员添加访问控制修饰符2.给6个对象类添加图片属性
Shoot射击游戏第六天:1.设计窗口的宽和高为常量,适当地方做修改2.画对象: 1)想画对象需要获取对象的图片,每个对象都得获取图片, 意味着获取图片为共有行为,所以设计在超类FlyingObject中, 每个对象获取图片的行为是不同的,所以设计为抽象方法 ----在FlyingObject中设计抽象方法getImage()获取对象的图片 2)获取图片时需要考虑对象的状态,因为不同状态下获取的图片是不同的, 每个对象都有状态,所以将状态设计在超类中,一般为常量 对象状态分三种:活着的、死了的、删除的 ----FlyingObject中设计LIFE、DEAD、REMOVE常量,state表示当前状态 获取图片时需在判断对象的状态,而每个对象都能判断状态, 所以判断状态行为为共有行为,设计在FlyingObject超类中, 每个对象判断状态的行为都一样,所以设计为普通方法 ----FlyingObject中设计isLife()、isDead()、isRemove() 3)在6个派生类中重写抽象方法getImage()获取图片 3.1)天空Sky,直接返回image 3.2)子弹Bullet: 3.2.1)若活着的,返回image 3.2.2)若死了的,改为删除状态 3.3)英雄机Hero: 3.3.1)若活着的,返回images[0]和images[1]来回切换 3.4)小敌机Airplane: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 3.5)大敌机BigAirplane: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 3.6)小蜜蜂Bee: 3.4.1)若活着的,返回images[0] 3.4.2)若死了的,返回images[1]到images[4]轮换,4后删除 4)获取了图片,则可以开始画对象了,每个对象都能画,为共有行为 因为每个对象画图片的行为都是一样的,所以设计为普通方法 ----在FlyingObject中设计普通方法paintObject()实现画对象 5)天空需要画两张图片,所以在天空Sky中重写paintObject() ----在Sky中重写paintObject()画两张图片 6)画对象行为写好后,在窗口上调用即可 ----在World中重写paint()
Shoot射击游戏第七天:1.敌人入场: 1)敌人是由窗口产生的,所以在World类中设计nextOne()生成敌人 2)敌人入场是定时发生的,所以在run中调用enterAction()实现敌人入场 在enterAction()中: 每400毫秒获取敌人对象,enemies扩容,装到最后一个元素上2.子弹入场: 1)子弹是由英雄机发射出来的,所以在Hero类中设计shoot()生成子弹对象 2)子弹入场是定时发生的,所以在run中调用shootAction()实现子弹入场 在shootAction()中: 每300毫秒获取子弹对象,bullets扩容,数组的追加3.飞行物移动: 1)飞行物移动为共有行为,所以在FlyingObject中设计抽象方法step() 派生类中重写step() 2)飞行物移动是定时发生的,所以在run中调用stepAction()实现飞行物移动 在stepAction()中: 天空动,遍历敌人敌人动,遍历子弹子弹动
Shoot射击游戏第八天:1.英雄机随着鼠标移动: 1)英雄机随着鼠标动为英雄机的行为,在Hero中设计moveTo()实现英雄机移动 2)英雄机随着鼠标动为事件触发的,所以在侦听器重写mouseMoved()鼠标移动事件 在mouseMoved()中: 获取鼠标的x和y坐标,英雄机动2.删除越界的敌人和子弹: 1)在FlyingObject中设计outOfBounds()检测敌人是否越界 在Bullet中重写outOfBounds()检测子弹是否越界 2)删除越界为定时发生的,所以在run()中调用outOfBoundsAction()实现删除越界敌人和子弹 在outOfBoundsAction中: 声明不越界敌人/子弹数组,遍历敌人/子弹数组,获取对象, 判断若对象不越界,则将对象添加到不越界敌人/子弹数组中 最后将不越界敌人/子弹数组,复制到enemies/bullets中3.设计Enemy得分接口,Airplane和BigAirplane实现Enemy接口 设计Award奖励接口,Bee实现Award接口
24.多态:
1)意义:
1.1)同一类型的引用,指向不同的对象时,有不同的实现 -----行为的多态:cut(),run(),step()... 1.2)同一个对象,被造型为不同的类型时,有不同的功能 -----对象的多态:我,你,水...
2)向上造型/自动类型转换:
2.1)超类型的引用指向派生类的对象 2.2)能造型成为的数据类型有: 超类+所实现的接口 2.3)能点出来什么,看引用的类型
3)强制类型转换,成功的条件只有如下两种:
3.1)引用所指向的对象,就是该类型 3.2)引用所指向的对象,实现了该接口或继承了该类
4)强转时若不符合如上条件,则发生ClassCastException类型转换异常
建议:强转之前先通过instanceof判断引用指向的对象是否是该类型
我真正想让它留在窗口上的: 不越界的,并且,LIFE/DEAD(非REMOVE的)
LIFE/DEAD/REMOVE
int score = 0; //玩家得分//子弹与敌人的碰撞public void bulletBangAction() { for(int i=0;i<bullets.length;i++){ Bullet b = bullets[i]; for(int j=0;j<enemies.length;j++){ FlyingObject f = enemies[j]; if(b.isLife() && f.isLife() && f.hit(b)){ //撞上了 b.goDead(); f.goDead();
//Airplane(1)
//BigAirplane(3)
//BigYellowBee(6)
if(f instanceof Enemy){
Enemy e = (Enemy)f;
score += e.getScore();
}
//Bee()
//BigYellowBee()
if(f instanceof Award){
Award a = (Award)f;
int type = a.getAwardType();
switch(type){
case Award.DOUBLE_FIRE:
hero.addDoubleFire();
break;
case Award.LIFE:
hero.addLife();
break;
}
}
//复用性差,扩展性差,维护性差
if(f instanceof Airplane){
Airplane a = (Airplane)f;
score += a.getScore();
}
if(f instanceof BigAirplane){
BigAirplane ba = (BigAirplane)f;
score += ba.getScore();
}
if(f instanceof Bee){
Bee b = (Bee)f;
int type = b.getAwardType();
switch(type){
case Award.DOUBLE_FIRE:
hero.addDoubleFire();
break;
case Award.LIFE:
hero.addLife();
break;
}
}
if(f instanceof BigYellowBee){
BigYellowBee byb = (BigYellowBee)f;
score += byb.getScore();
int type = byb.getAwardType();
switch(type){
case Award.DOUBLE_FIRE:
hero.addDoubleFire();
break;
case Award.LIFE:
hero.addLife();
break;
}
}
}
}
}}
若撞上了:1)敌人去死、子弹去死2)若被撞的为小敌机,则玩家得1分 大敌机,则玩家得3分 小蜜蜂,则英雄机增命或增火力
state=LIFEstate=DEAD
英雄机与敌人的碰撞:
class FlyingObject{ //敌人 //敌人撞子弹/英雄机 public boolean hit(FlyingObject other){ this:敌人 other:子弹/英雄机 }}
?处为何种类型: 既能接收Bullet对象,也能接收Hero对象
class Bullet{ //子弹 //子弹撞敌人 public boolean hit(FlyingObject other){ this:子弹 other:敌人 }}
Aoo o = new Boo();Boo o1 = (Boo)o; //符合条件1Inter1 o2 = (Inter1)o; //符合条件2//Coo o3 = (Coo)o; //ClassCastException类型转换异常if(o instanceof Coo){ //false Coo o4 = (Coo)o;}
System.out.println(o instanceof Boo); //trueSystem.out.println(o instanceof Inter1); //trueSystem.out.println(o instanceof Coo); //false
interface Inter1{}class Aoo{}class Boo extends Aoo implements Inter1{}class Coo extends Aoo{}
//超类大,派生类小Person o1 = new Student(); //向上造型/自动类型转换
我 me = new 我();讲师 o1 = me;孩子他妈 o2 = me;老公的老婆 o3 = me;
o1.授课();o2.揍他();o3.咬他();o3.收工资();
me.授课();me.揍他();me.咬他();me.收工资();
interface 讲师{ void 授课();}interface 孩子他妈{ void 揍他();}interface 老公的老婆{ void 咬他(); void 收工资();}class 我 implements 讲师,孩子他妈,老公的老婆{ public void 授课(){} public void 揍他(){} public void 咬他(){} public void 收工资(){}}
动物 o1 = new 老虎();动物 o2 = new 鱼();动物 o3 = new 鸟();
o1.run(); //地上o2.run(); //水里o3.run(); //天上
abstract class 动物{ abstract void run();}class 老虎 extends 动物{ void run(){ 在地上跑 }}class 鱼 extends 动物{ void run(){ 在水里游 }}class 鸟 extends 动物{ void run(){ 在天上飞 }}
人 o1 = new 理发师();人 o2 = new 外科医生();人 o3 = new 演员();
o1.cut(); //剪发o2.cut(); //开刀o3.cut(); //停止表演
abstract class 人{ abstract void cut();}class 理发师 extends 人{ void cut(){ 剪发 }}class 外科医生 extends 人{ void cut(){ 开刀 }}class 演员 extends 人{ void cut(){ 停止表演 }}
功能:1.子弹与敌人的碰撞2.画分和画命
课上听得懂,自己写不出来----------------不需要重听听不懂我在说什么------------------------下个月见
25.内存管理:
1)堆: 1.1)存储new出来的对象(包括实例变量) 1.2)垃圾:没有任何引用所指向的对象 垃圾回收器(GC)不定时到内存中清扫垃圾, 回收过程是透明的(看不到的),不一定发现垃圾就立刻回收, 调用System.gc()建议虚拟机尽快调用GC来回收 1.3)实例变量的生命周期: 创建对象时存储在堆中,对象被回收时一并被回收 1.4)内存泄漏:不再使用的对象还没有被及时的回收 建议:不再使用的对象及时将引用设置为null 2)栈: 2.1)存储正在调用的方法中的局部变量(包括方法的参数) 2.2)调用方法时会在栈中为该方法分配一块对应的栈帧, 栈帧中存储局部变量(包括方法的参数), 当方法调用结束时,栈帧被清除,局部变量一并失效 2.3)局部变量的生命周期: 调用方法时存在栈中,方法结束时与栈帧一次消失 3)方法区: 3.1)存储.class字节码文件(包含方法、静态变量) 3.2)方法只有一份,通过this来区分具体的访问对象
26.面向对象三大特征:常见面试题
1)封装: 1.1)类:封装的是对象的属性和行为 1.2)方法:封装的是特定的业务逻辑功能实现 1.3)访问控制修饰符:封装的是具体的访问权限 2)继承: 2.1)作用:代码复用 2.2)超类:所有派生类所共有的属性和行为 接口:部分派生类所共有的行为 派生类:派生类所特有的属性和行为 2.3)传递性,单一继承、多接口实现 3)多态: 3.1)意义: 3.1.1)行为的多态(所有抽象方法都是多态的) 3.1.2)对象的多态(所有对象都是多态的) 3.2)向上造型、强转类型转换、instanceof判断 3.3)表现形式: 3.3.1)重写:根据对象的不同来表现多态 3.3.2)重载:根据参数的不同来表现多态当程序的运行结果与你所预期的结果不同时:
1)打桩: System.out.println(数据);2)Debug调试工具: 2.1)添加断点 2.2)掌握4个键: 2.2.1)F5:单步调试(会进入到方法中) 2.2.2)F6:逐过程调试(不会进入到方法中) 2.2.3)F7:结束方法的调试 2.2.4)F8:直接跳到下一个断点(若后面没有断点则结束调试) 2.3)会看2个东西: 2.3.1)会看变量 2.3.2)会添加监视(选中表达式右键Watch)
System.out.println();System.out.println(234);System.out.println(24.56);System.out.println('你');System.out.println(true);System.out.println("Hello");
所有对象都是多态的
Object:是所有类的鼻祖
Aoo o1 = new Aoo();Object o2 = new Aoo();
Airplane o1 = new Airplane();FlyingObject o2 = new Airplane();Enemy o3 = new Airplane();Object o4 = new Airplane();
实例变量:1)类中,方法外2)创建对象时存储在堆中,对象被回收时一并被回收3)有默认值
局部变量:1)方法中2)调用方法时存在栈中,方法结束时与栈帧一次消失3)没有默认值
Aoo o = new Aoo();------------------a=0o.show(5);--------------------------b=5
class Aoo{ int a; void show(int b){ int c; System.out.println(a); //0 System.out.println(b); //5 System.out.println(c); //编译错误 }}
垃圾回收器(GC)
功能:1.英雄机与敌人的碰撞2.检测游戏结束3.画状态