面向对象编程(oop)

Java是一门面向对象的编程语言

1)什么是面向对象
Java世界中的所有组成都可以理解为对象
对象:东西
2)为什么需要面向对象编程
减少代码冗余
提高代码复用性
增强程序的可维护性和可维护性
3)生活中的对象(东西)
万物皆对象
人类认识世界是先认识对象,再认知类型
现实世界中是先有对象后有类型
4)Java中的类和对象
4.1)Java中是先有类型后有对象
4.2)如何创建一个类
public class <类名>{
//类中的代码
}
面向对象编程思想
类中可以包含变量,这个变量称为属性
类中可以包含方法,便是这个对象的功能
4.3)对象的实例化
<类名> <对象名> = new <类名>();
如:Emp man = new Emp();
最终操作属性和方法的一定是对象

方法重载:

在同一个类中出现了相同方法的情况
特征:
1.同一类中方法名相同,参数列表不同
2.参数列表的个数不同;参数对应的数据类型不同;参数顺序不同
3.与返回值无关

构造方法:

1.什么是构造方法(构造函数)
类在实例化对象时,用于一个特定方法,一般用于对属性赋初值
2.构造方法的特点
1)构造方法实例化对象时一定会运行, new <类名>();就是在调用构造方法
2)如果不写构造方法,系统会默认分配一个构造方法
3)如果要编写构造方法,方法名必须和类名相同,构造方法没有返回值类型:public <类名>(){ }
4)如果编写了构造方法,系统的默认构造方法就消失了
5)构造方法也可以有参数
6)构造方法除实例化时不能调用
7)构造方法可以重载
8)public可以省略

this关键字:

1)this关键字是对当前对象自身的引用
this是对当前对象自身的引用

class Dog{
	String name;
	int age;
	double weight;
	String strain;
	public Dog(){	
	}
	public Dog(String name,int age,double weight,String strain){
		this.name = name;
		this.age = age;
		this.weight = weight;
		this.strain = strain;
	}
	public void show(){
		System.out.println("This is a dog");
	}
}

2)局部变量和成员变量
2.1)成员变量可以在类中的任何方法使用
2.2)局部变量只能在定义它的方法中使用
2/3)成员变量有默认初始值,局部变量没有初始值,必须赋值后才能使用
2.4)优先级不同,局部变量具有更高的优先级,局部变量和成员变量可以重名
小结:一般情况下只有重名时,才必须使用this来区分变量,但是如果没有重名,使用成员变量时,实际上默认加了this
3)this关键字的使用
3.1)this.属性:就是获取类名中名称匹配的属性
3.2)this.方法:写法不常见
3.3)this():调用构造方法,只能写在构造方法中的第一行

class Gun{
	public Gun(){
		System.out.println("无参构造");
	}
	public Gun(int x){
		this();
		System.out.println("int");
	}
	public Gun(String s){
		this(10);
		System.out.println("String");
	}
}

数据类型

1)基本数据类型
基本数据类型相互赋值时,直接获得对方的值
修改其他变量的值,不会影响自身的值
2)引用数据类型
(String,数组,自造类)
引用数据类型在赋值时,获得的是对方的引用
多个引用指向同一个对象时,任何一个应用修改对象的值,会影响其他引用

public class DogDemo {
public static void main(String[] args) {
	Dog d = new Dog("小黑",5,15.7);
	Dog dd = d;
	Dog ddd = new Dog();
	System.out.println(d.name);
	dd.name = "小白";
	System.out.println(d.name);}
}

class Dog{
	String name;
	int age;
	double weight;
	public Dog(){
	}
	public Dog(String name,int age,double weight){
		this.name = name;
		this.age = age;
		this.weight = weight;
	}
}

关于null:
null指的是该引用没有指向任何对象
同时null也是引用类型的默认值
注意:null没有指向任何对象,所以也不能调用任何方法或属性
NullPointerException:空指针异常:
代码中有指向null的对象调用了方法,或使用了属性

引用类型数组
数组中的数据类型是引用数据类型
<数据类型>[] <数组名> = new <数据类型>[长度];
数组声明后,引用数据类型的默认值是null
注意 空指针异常的发生
向数组中赋值
<数组名>[下标] = new<类名>(参数);
遍历:
for(int i=0;i<n;i++){
<数组名>[i].方法名();
}

public static void main(String[] args) {
		Dog[] dogs = new Dog[4];
		//dogs数组默认值null
		
		/*Dog[] dogs = {new Dog("小虎",5,5.5),
		              new Dog("小龙",6,5.5),
		              new Dog("小7",7,7.5),};//直接赋值*/
		              
		/*Dog d = new Dog("小虎",5,5.5);
		dogs[0] = d;*/
		
		dogs[0] = new Dog("beibie",4,5.3);
		dogs[0].show();
	}
class Dog{
	String name;
	int age;
	double weight;
	public Dog(){
		
	}
	public Dog(String name,int age,double weight){
		this.name = name;
		this.age = age;
		this.weight = weight;
	}
	public void show(){
		System.out.println(this.name);
	}
}

4.多维数组
1)什么是二维数组
数组中的元素又是数组
2)声明时
数据类型[][] 变量名 = new 数据类型[长度][],遍历时需要循环嵌套

5.继承

面向对象三大特征((抽象)、封装、继承、多态)之一
1)什么是继承
继承就是在面向对象编程中,代码复用的一种方式
2)为什么使用继承
减少代码冗余,提高程序的可维护性和可扩展性
3)怎样使用继承
3.1)在多个类似属性的类存在时,为了减少维护困难的风险,减少代码冗余,我们可以将多个类中相同的代码抽取到一个类中。这个类我们称为父类(超类、基类)。
3.2)继承的格式
class <子类名> extends <父类名>{
}
子类继承父类
3.3)继承时两个类需要满足is-a(是一个)的关系
3.4)其中被继承的类叫父类,主动继承的类叫子类(派生类)
4)继承之后,子类中和子类的对象可以调用父类中的属性和方法
5)继承的特性
5.1)Java中的继承是单根的,Java中不允许一个类继承多个父类
5.2)Java的继承是有传递性的,子类中不但能使用父类中的属性和方法,祖先类中的属性和方法也能继承到子类
5.3)与要了解,Java中的Object类是所有类的父类。如果定义类时不继承任何类,都默认继承object类

6)继承下构造方法的执行顺序
子类在实例化之前先运行父类构造方法,再运行子类构造方法
因为子类对象中 包含着父类对象的

7)super关键字
当父类没有无参构造时子类的构造方法报错了,因为子类构造默认调用父类的无参构造,想要主动调用父类构造需要super关键字
7.1)在默认情况下,子类构造默认调用父类无参构造,相当于编写了super();
7.2)如果主动编写了super();关键字来调用父类构造,就按照匹配的父类构造运行
7.3)super();必须编写在构造方法中的第一行
8)super的作用
super();是当前对象对父类对象的引用
8.1)super.属性:调用父类中的属性
8.2)super.方法:调用父类中的方法
8.3)super();调用父类中的构造,必须在构造方法中的第一行
字符串在判定和另外字符串是否相等时,相等时需要使用s.equals(“xx”);的方式

9)向上造型(向上转型):
使用向上造型,也是为了减少代码冗余
将子类对象赋给父类的引用,父类引用指向子类对象
[父类类型] <变量名> = new [子类类型](参数列表)
Pet d = new Dog(“lo”, 4, 3.4, “keji”);//接受对象的类型是父类类型
9.1)父类类型的对象只能调用到父类中的属性和方法,不能调用子类的独有的属性和方法
9.2)使用向上造型,可以将不同的多个子类队形放到同一个父类类型数组中

10)方法重写(方法覆盖、override)
10.1)在子类中,编写一个和父类中方法名相同,参数列表相同,返回值类型和修饰符也形同的方法。那么这个方法就是对父类中这个方法的重写
10.2)方法重写完成后,使用向上造型获得的父类对象,在调用子类重写方法时,运行的是子类重写后的方法
10.3)方法重写的详细规则:
必须完全相同的:1.方法名 2.参数列表;
可以不同的:1.返回值如果是void或基本数据类型必须完全相同;如果返回值是引用数据类型,可以相同,也可以是返回父类返回值类型的子类;2.子类重写的方法的修饰符(public等)级别不能比父类更严格;3.子类抛出的异常类型和父类相同或是其子类

class Aoo{
	public Drink he(){
		Dring d = new Drink();
		return d;
	}
}
class Boo extends Aoo{
	public Cola he(){
		Cola c = new Cola();
		return c;
	}
}

10.4)方法重载和方法重写

java先写方法还是先写测试 java是先有类还是先有对象_java


方法重载:编译期绑定,在代码编译时就决定运行那个方法了

方法重写:运行期绑定,在程序运行时才决定运行那个子类的方法

package

1)作用:一个存放功能类似或特殊分类规则java类的文件夹
1.1)不同包中的类是可以重名的,避免命名冲突
1.2)区分不同包中的相同类名,开发时在自己创建的包中创建类,不用担心和别人重名
1.3)包中所有字母均小写,用.分割
1.4)在实际开发中,通常包名前缀使用公司域名反写

import关键字

1)我们之前访问的大多是当前包中的类,所以访问时不用导包,如果我们访问的是其他包中的类,可以使用import指定要导入包的路径
2)如果不想使用关键字导包,代码中直接使用全类名指定一个类
com.szh.a.Aoo a = new com.szh.a.Aoo();
3)在java中系统默认将java.long包下所有类引入

访问修饰符

1)访问修饰符是限制其他类访问当前类成员的特殊修饰符

2)java类中能够将一些比较隐私的细节不被随意访问

3)访问修饰符的级别:

当前类 同包 不同包的子类 不同包的其他类

4)访问修饰符

private、默认、protected、public

4.1)所有成员均可以使用四种访问修饰符(属性、构造、方法)

4.2)class只能是public或默认(被public修饰的类名称必须和类名相同)

java先写方法还是先写测试 java是先有类还是先有对象_构造方法_02

4.封装

隐藏很多实现细节,屏蔽掉不必要的访问,我们编写的程序也需要封装,将一些不必要的细节不提供对外访问权限
通常情况下,属性都是私有的
封装属性的步骤:
1.将所有属性设置为private
2.编写访问属性的方法(setters和getters) :alt+shift+s
3.在调用时通过共有的方法访问

final关键字

final(最终)关键字也是修饰符
可以修饰类、方法、属性、局部变量
5.1)final修饰类:被final修饰的类不允许被继承。
为了保证系统的稳定性,有一些类设计时不想被继承,java系统总有很多类都是不能被继承的
5.2)final修饰方法
被final修饰的方法子类不能重写
5.3)final修饰属性
被final修饰的属性值,必须赋初值(或在构造方法中赋初值),且属性不能修改
即:被final修饰的属性必须在实例化对象完成之前赋初值
5.4)final修饰局部变量:
被final修饰的局部变量只能赋值一次且不能修改

static关键字

static(静态)也是修饰符,static只能修饰成员(属性、方法、代码块)
1)修饰属性
什么时候用static修饰属性:当这个类的所有对象共享一个数据时,这个数据就用static修饰
静态属性也称类属性,是属于类,而不属于某个对象;普通的是属性也称为实例属性,属于对象。
在使用静态属性时,官方建议使用类名.调用
静态属性被java保存到方法区中,方法区中的静态属性只保存一份,打到数据共享和节省内存的目的
在类加载时就已经出现在方法区中
2)修饰方法
被static修饰的方法就是静态方法
方法中的代码若只和该方法的参数相关,但是和对象无关,就可以将该方法定义为静态的
好处:将方法定义为静态之后,可以直接使用类名.调用
缺陷:静态方法中只能调用静态属性,不能调用实例属性
静态方法中是加上是没有this关键字的引用
3)修饰代码块
初始化代码块
运行在构造方法运行之前
static修饰初始化代码块,程序运行一次,静态块也只运行一次,在JVM加载类时运行
4)常量
在java中同时被static和final同时修饰的属性称为常量
必须直接赋初值,使用类名调用。常量在编译时直接将常量的值替换到需要的位置
敞亮的命名必须所有字母均大写,使用_分割单词

抽象类

1.抽象类
抽象类就是在程序运行中不存在对象的类
1)抽象类不能实例化
2)在class前加abstract关键字
3)抽象类可以编写抽象方法,抽象类中的抽象方法数量不限

2.抽象方法
就是抽象类中由于对象的不确定而无法具体实现的方法
1)抽象方法没有方法体
2)在返回值类型前加abstract关键字
3)除非子类也是抽象类,否则抽象方法必须在子类中被重写
4)抽象方法只能写在抽象类中
注意:final和abstract不能同时修饰

3.抽象类的意义
1)减少代码冗余
2)抽象类有利于标准化的制定,方便程序结构的设计
3)更自然的使用向上造型

内部类

内部类就是一个类内部定义的一个类
外部类我们称之为Outer,内部类称之为Inter
1)成员内部类
就是在编写成员的位置编写内部类
使用时当做类的成员使用
任何内部类都会在编译时产生自己独立的class文件
1.1)可以使用所有四种访问修饰符
1.2)内部类可以有自己的属性和方法
1.3)当内部类和外部类有成员重名时,内部类中要使用外部类的成员需要
<外部类名>.this.<外部类成员名> = 20;
1.4)私有属性内部类和外部类共享
1.5)在其他类中实例化内部类的语法
<外部类名>.<内部类名> 变量名 = new <外部类名>().new<内部类名>();
2)局部内部类
就是声明在方法里的内部类,只能在当前方法中使用
2.1)不能使用修饰符
2.2)局部内部类也可以通过 <外部类名>.this获得外部对象
2.3)局部内部类只能在声明他的方法中使用
2.4)其他类不能实例化局部内部类的对象
3)静态内部类
静态内部类就是使用了static关键字修饰的成员内部类,使用时当做静态成员使用
3.1)使用static修饰,还可以使用其他四种修饰符
3.2)静态内部类不能获得外部类对象的实例属性或方法
3.3)在其他类中实例化静态内部类的语法
<内部类名> 变量名 = new <外部类名>.<内部类名>();
4)匿名内部类(用得到)
实际上匿名内部类是一个局部内部类的特殊形式,这个局部内部类在方法中使用,但是没有名字
4.1)必须使用一个类或接口当做父类
4.2)匿名内部类定义时是在实例化对象后加一对{},在{}中编写匿名内部类的代码
4.3)在匿名内部类中使用创建它的方法中的局部变量时要保证这个局部变量的值没有变化过(JDK1.6之前,匿名内部类只能使用方法中被final修饰的局部变量)

计时器

需要在每个一段时间后周期性的调用某个方法的机制
1)实例化计时器对象 Timer(java.util.Timer)
2)编写周期性调用的方法内容,使用TimerTask(java.util)
3)开启计时器周期性调用编写好的方法

//游戏的主计时器
	Timer timer = new Timer();
//定义计时器的时间间隔
	int interval = 50;
	TimerTask task = new TimerTask(){
		public void run(){
			//如果游戏在运行状态
			if(state == RUNNING){
				stepAction();//开始移动
				enterAction();//敌人进场
				shootAction();//子弹进场
				outOfBoundsAction();//移除越界内容
				bulletHitAction();//子弹碰撞敌机
				heroHitAction();//英雄机撞敌机
				checkGameOverAction();//检测英雄机生命值,为0的时候结束
			}
			repaint();//重新绘制整个窗体
		}
	};

接口(像抽象类)

在java中为了实现java中的多继承,也为了让java程序更灵活,java程序框架更容易实现
使用接口
1)什么是接口
接口也是java中的一种数据类型
1.1)接口声明时将class替换为interface
1.2)接口不能实例化
1.3)接口中的属性只能是公有静态常量
1.4)接口中所有方法均为抽象方法
1.5)接口中不能编写构造
1.6)接口允许java类多继承
2)使用接口
2.1)在定义类时,继承类之后编写implements关键字;
在关键字后编写要继承的接口名称,多个接口用逗号分隔
2.2)接口可以继承接口,而且是多继承;
接口继承接口时,使用extends关键字;
子接口被实现时要求实现类实现子接口和父接口中的所有抽象方法
2.3)接口可以使用匿名内部类实现
3)接口的优点
3.1)实现了java中的多继承,有助于程序扩展
3.2)使用接口可以降低java程序的耦合性
3.3)工作中接口就是你今天的任务

多态

1)什么是多态
同一个父类的不同子类对同一个方法的触发做出不同响应
2)为什么要使用多态
减少代码冗余,提高程序的可扩展性
3)如何实现多态
3.1)编写父类,编写子类继承父类
3.2)子类重写父类方法
3.3)使用向上造型接受父类方法
3.4)使用父类引用调用子类重写后的方法
4)父类引用调用子类独有方法
4.1)子类如果含有独有的方法
4.2)父类想要调用子类中独有方法需要强制类型转换
4.3)如果强转类型不匹配,会发生异常(类型强转异常 ClassCastException)
强转的格式:(<子类的类型>)<父类的引用>
5)instanceof 关键字
功能:判断一个对象是否属于某个类型
语法:<对象名(引用)> instanceof <类名(接口名)>
结果:是一个boolean类型的值,返回true or false

1.垃圾回收管理机制(GC机制)
1)什么是GC
JVM运行时自带的一套内存管理系统
2)为什么需要GC
如果内存放任不管,时间长了总会出现内存满的情况,即内存泄漏(内存溢出)
为了减少或避免内存泄漏,java中就出现了GC
3)其他语言是怎样管理内存中的垃圾的
C++:没有类似java中GC机制,所有实用玩的对象都需要程序眼自己回收,程序员释放对象占用的空间需要调用对象的析构函数
4)java程序员不用考虑垃圾回收问题
GC有点:
1)程序员专心研究业务,不需要担心垃圾回收问题
2)减少代码量,让java程序看上去更简洁
GC缺点:
1)GC也是一条线程,也会占用资源
2)GC回收垃圾的时效性不是非常及时
3)GC只会回收java程序运行过程中产生的垃圾
5)GC的回收过程
栈中存什么:局部变量,在方法中声明的变量
方法结束,栈中所有数据都会变成垃圾,会被GC回收
堆中存什么:对象和类中的属性
代码中实例化的对象都会存在堆中
JVM只有一个堆队中的对象如果没有被其他类型引用,会被GC回收
6)finalize方法
是Object类中一个保护类型的方法,该方法会在对象被垃圾回收前有GC自动调用
7)system.gc()方法
system.gc()方法用于通知GC机制尽快回收垃圾