多线程: Java 内置多线程,C++ 没有内置的多线程机制,必须调用操作系统的多线程功能来进行多线程程序的设计。
动态: 类是运行时动态加载的
Java SE : JAVA 标准版或 Java 标准平台。提供了标准的JDK
- Java EE : 企业版平台。
编写源文件 (使用编译器)—— 编译源文件 (产生)—— 字节码 (使用解释器)—— 执行字节码
编译以后将生成 .class 字节码文件 javac.exe 编译器
java.exe 解释器 解释器执行的类名必须是主类的名字
java 虚拟机首先将程序需要的字节码文件加载到内存,然后解释执行字节码文件。
当虚拟机将Hello.class 加载到内存时,就为主类中main方法分配了入口地址,以便JAVA 解释器调用main 方法开始运行程序。
- 封装性
- 继承:子类可以继承父类的属性和行为,即继承父类所具有的数据和数据上的操作,同时又增添子类独有的数据和数据上的操作。
- 多态
1. 类体
抽象的关键是抓住事物的两个方面:
- 属性
- 行为
- 变量的声明: 用来存储属性的值(体现对象的属性)
- 方法的定义: 方法可以对类中声明的变量进行操作,即给出算法(体现对象所具有的行为)
类 = 变量的声明+方法的定义
成员变量
- 变量的声明
- 方法的定义 返回类型为JAVA中的任意一种数据类型。 void 类型时,则不需要返回数据。
声明变量部分所声明的变量被称为成员变量或域变量。
成员变量的类型: 可以是java中的任何一种数据类型
- 包括基本类型:整型,浮点型,字符型,逻辑类型
- 引用类型: 数组,对象和接口
局部变量:只在方法内有效,而且与其声明的位置有关。
- 区分成员变量和局部变量:两者名字相同,成员变量被隐藏,则该成员变量在这个方法内暂时失效。
- 如果想用被隐藏的成员变量,则必须使用关键字 this
- 成员变量有默认值,但局部变量没有默认值,因此使用前必须保证有具体的值。
构造方法与对象的创建
- 构造方法
是类中一种特殊方法,当程序用类创建对象时需使用它的构造方法,类中的构造方法的名字必须与它所在的类的名字完全相同,而且没有类型。允许在一个类中编写若干个构造方法,但必须保证他们的参数不同。
参数不同: 参数的个数不同 ,或者个数相同时,某个参数的类型不同。 没有类型!!!
注意:如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法中没有语句。
- 创建对象
- 对象的声明
- 为声明的对象分配变量
- 对象的内存模型
- 声明对象时的内存模型
- 为对象分配变量后的内存模型
- 创建多个不同的对象 (创建对象就是为对象分配变量,并获得一个引用,以确保这些变量由该对象来操作管理)
new 运算符只能和类的构造方法进行运算,运算的最后结果是一个十六进制的数,这个数称作为对象的引用。
即 new basd() 是一个引用。在new 计算出这个引用之前,首先给basd 类中的成员变量分配内存空间,然后执行构造方法中的语句,这个时候,不能称对象已经诞生,因为还没有计算出引用,即还没有确定被分配了内存的成员变量是“who”的成员。
当计算出引用后,即new basd() 表达式已经有值后,对象才诞生。
注意:
- 对象的引用存在栈中,对象的实体(分配给对象的变量)存在堆中。
- 栈和堆都是java用来在RAM中存放数据的地方。java自动管理堆和栈
- 栈的优势,存取速度比堆要快,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
- 堆的优势,可以动态分配内存 大小,生存期也不必事先告诉编译器。
- java的垃圾收集器会自动收走这些不再使用的数据。缺点是由于在运行时动态分配内存,存取速度较慢。
- 垃圾收集机制,周期地检测某个实体是否已不再被任何对象所拥有(引用),如果发现这样的实体,就释放实体占有的内存。
- 和C++ 不同,在java语言中,类有构造方法,但没有析构方法,java 运行环境有“垃圾收集”机制。
- “垃圾收集”发现堆中分配的实体不再被栈中任何对象所引用时,就会释放该实体在堆栈中占用的内存。因此JAVA中很少出现内存泄漏。
- 立即进行“垃圾收集”操作,可以让system类调用gc() 方法。
主类: 含有main 方法的类
从main 方法开始执行
每个源文件编译后产生若干个类的字节码文件。
当解释器运行一个java 应用程序时,java虚拟机将java应用程序需要的字节码文件加载到内存,然后再由java的虚拟机解释执行。
java 程序以“类”为基本单位。
引用类型参数的传值
当参数是引用类型时,“传值” 传递的是变量中存放的“引用”。而不是变量中的实体。
一个类声明的两个对象如果具有相同的引用,二者就具有完全相同的变量。
组合与复用
如果一个对象a组合了对象b,那么对象a就可以委托对象b调用其方法,即对象a以组合的方式复用对象b的方法。
实例成员与类成员
- 类体中包括成员变量的声明和方法的定义,而成员变量又可细分为实例变量和类变量。
- 在声明变量时,用关键字static 给予修饰的称作类变量,否则称为实例变量(类变量也称为static 变量,静态变量)
实例变量和类变量的区别
1 .分配给不同对象的实例变量占有不同的内存空间,改变其中一个对象的实例变量不会影响其他对象的实例变量
- 所有对象共享类变量,如果类中有类变量,当使用new运算符创建多个不同的对象时,分配给这些对象的这个类变量占有相同的一块内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量。
- 所有的对象的类变量是相同的一处内存空间,类变量的内存空间直到程序退出运行,才释放所占有的内存。
- 类变量不仅可以通过某个对象访问,也可以直接通过类名访问。
实例方法和类方法
- 实例方法不能通过类名调用,只能由对象来调用。
- 类方法不可以操作实例变量,这是因为在类创建对象之前,实例成员变量还没有分配内存。
- 对于static 方法, 不必创建对象就可以用类名直接调用它。
方法重载
两种多态:
- 重载(Overload): 一个类中可以由多个方法相同的名字,但这些方法的参数必须不同。
- 参数的个数不同
- 参数个数相同,但参数列表中对应的某个参数的类型不同
- 重写(Override) : 继承有关的多态
this关键字
this 表示某个对象,this 可以出现在实例方法和构造方法中,但不可以出现在类方法中。
- 在构造方法中使用this 代表使用该构造方法所创建的对象。
在实例方法中使用this
实例方法只能通过对象来调用,不能用类名来调用。
当this 关键字出现在实例方法中时,this 就代表正在调用该方法的当前对象。
- 实例成员变量的名字与局部变量的名字相同时,成员变量前面的“this.”或“类名.”就不能省略。
this 不能出现子在类方法中,这是因为类方法可以通过类名直接调用,这时,可能还没有任何对象诞生。
2. 包
包是JAVA 有效管理类的一个机制,不用java源文件中可能出现名字相同的类。
如果想区分这些类,就需要使用包名。
包名的目的就是有效区分名字相同的类
不同Java 源文件中的两个类名字相同时
可以通过隶属于不同的包来相互区分
3. 访问权限
- 私有变量和私有方法
用关键字 private 修饰的成员变量和方法称为私有变量和私有方法。其他类不能通过类名进行访问。
- 共有变量和共有方法
用public 修饰的成员变量和方法 ,其他类可以通过类名来进行访问。
- 友好变量和友好方法
不用private、 public 、protected 修饰符修饰的成员变量和方法。
同一个包中不同类,可以通过类名进行访问。
- 受保护的成员变量和方法
用protected 修饰的成员变量和方法。
同一个包中可以访问。
- public 类和友好类
- 可以在任何另外一个类中使用public 类创建对象
- 另外一个类使用友好类创建对象时,要保证它们是在同一个包中。
注: 1. 不能用Protected 和 private 修饰类
2. 访问限制修饰符按访问权限从高到底:public protected 友好的 private
4. 基本类型的类封装
Java 的基本数据类型包括boolean byte short char int long float 和 double
Java 同时也提供了与基本数据类型相关的类
实现了对基本数据类型的封装
这些类在 java.lang 包中
分别是 Byte、 Integer 、 Short 、 Long 、Float 、 Double Character
5. 对象数组
数组的元素是对象
Student [ ] stu;
stu = new Student[10];
class Student{
int number;
}
public class Example4_21{
public static void main(String args[]){
Student stu[] = new Student[10]; // 创建对象数组stu
for(int i = 0;i < stu.length;i++){
stu[i] = new Student();
stup[i].number = 101+i;
}
for(int i = 0;i < stu.length;i++){
System.out.println(stu[i].number);
}
}
}
6. JRE 扩展与jar 文件
使用jar.exe 命令把一些类的字节码文件压缩成一个jar 文件,然后将这个jar 文件存放到JAVA 运行环境(jre)
的扩展中,即将该jar 文件存放在JDK安装目录的jre\lib\ext文件夹中。
这样,Java应用程序就可以使用这个jar 文件中的类来创建对象了。
package moon.star;
public calss TestOne{
public void fTestOne(){
System.out.println("I am a method In TestOne class");
}
}
总结
- 类是组成Java 源文件的基本元素,一个源文件是由若干个类组成的。
- 类体可以有两种重要的成员: 成员变量和方法。
- 成员变量分为实例变量和类变量。类变量被该类的所有对象共享,不同对象的实例变量互不相同。
- 除构造方法外,其他方法分为实例方法和类方法。类方法不仅可以由该类的对象调用,也可以用类名调用;而实例方法必须由对象来调用。
- 实例方法既可以操作实例变量也可以操作类变量,当对象调用实例方法时,方法中的成员变量就是指分配给该对象的成员变量,其中的实例变量和其他对象的不相同。即占有不同的内存空间。而类变量和其他对象的相同,即占有相同的内存空间。类方法只能操作类变量,当对象调用类方法时,方法中的成员变量一定都是类变量。也就是说,该对象和所有的对象共享类变量。
- 通过对象的组合可以实现方法复用。
- 在编写Java源文件时,可以使用import 语句引入有包名的类。
- 对象访问自己的变量以及调用方法受访问权限的限制。
7. 子类与继承
Java中不支持多重继承,即子类只能有一个父类。 “is-a”
子类
用关键字extends 来定义一个类的子类
class 子类名 extends 父类名{
}
子类的继承性
成员变量和方法都可以在在子类中直接使用
子类和父类不在同一个包中的继承性
当子类和父类不在同一个包中时,父类中Private 和 友好访问权限的成员变量不会被子类继承。
子类只能继承父类中的protected 和 public 访问权限的成员变量作为子类的成员变量。
同样,子类只继承父类中的protected 和 public 访问权限的方法作为子类的方法。
注:
如果B是A 的子类,C是B的子类,D又是C的子类
- 对于子类D 自己声明的protected 成员变量的方法,只要other类和D类在同一个包中,object 对象就可以访问这些protected 成员变量和方法。
- 对于子类D从父类继承的protected 成员变量或方法,需要追溯到这些protected 成员变量或方法所在的“祖先”类,例如是A 类,只要Other 类和A 类在同一个包中,object 对象能访问继承的protected变量和protected 方法。
8 .子类与对象
子类不继承父类的私有成员变量
子类和父类不再用一个包中,子类不继承父类的友好成员变量。
用子类创建对象时,父类的成员变量也都分配了内存空间,但只将一部分作为分配给子类对象的变量。
但子类还有一部分方法是从父类继承的,这部分方法却可以操作这部分未继承的变量。
instanceof 运算符
instanceof 运算符 是Java 独有的双目运算符
左面的操作元是对象
右面的操作元是类
当左面的操作元是右面的类或其子类所创建的对象时
Instanceof 的结果是TRUE 否则 未 false
成员变量的隐藏和方法重写
- 成员变量的隐藏
- 子类对象以及子类自己定义的方法操作与父类同名的成员变量是指子类重新声明的这个成员变量。
- 子类对象仍然可以调用从父类继承的方法操作被子类隐藏的成员变量,也就是说,子类继承的方法所操作的成员变量一定是被子类继承或隐藏的成员变量。
- 方法重写
子类通过重写可以隐藏已继承的方法(方法重写称为方法覆盖(method overriding))
如果子类可以继承父类的某个方法,那么子类就有权利重写这个方法。
方法重写:
- 这个方法的类型和父类的方法的类型一致或者是父类的方法的类型的子类型,
- 这个方法的名字、参数个数、参数的类型和父类的方法完全相同。
- 重写方法既可以操作继承的成员变量、调用继承的方法,也可以操作子类新声明的成员变量、调用新定义的其他方法,但无法操作被子类隐藏的成员变量和方法。
- 如果子类想使用被隐藏的方法或成员变量,必须使用关键字super.
- 重写方法时不能降低访问权限,但可以提高访问权限。
- super 关键字
如果在子类中想使用被子类隐藏的成员变量或方法,就需要使用关键字super
- 使用super 调用父类的构造方法
当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法。
如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就调用父类的不带参数的构造方法。
由于子类不继承父类的构造方法,因此,子类在其构造方法中需使用super 来调用父类的构造方法,而且super必须是子类构造方法中的头一条语句,即如果在子类的构造方法中,没有明显地写出super关键字来调用父类的某个构造方法,那么默认有: super()
final 关键字
final 关键字可以修饰类、成员变量和方法中的局部变量
- final 类
final 类不能被继承,即不能有子类。 出于安全考虑。
- final 方法
如果用final 修饰父类中的一个方法,那么这个方法不允许子类重写。
不允许子类隐藏可以继承的final 方法。(老老实实继承,不许做篡改)
- 常量
如果成员变量或局部变量被修饰成为final ,那它就是常量。
对象的上转型对象
继承与多态
父类的某个方法被其子类重写时,可以各自产生自己的功能行为。
abstract 类 和 abstract 方法
只许声明,不许实现(没有方法体)
而且不允许使用final 和 abstract 同时修饰一个方法或类
也不允许使用static 修饰abstract 方法,即abstract 方法必须是实例方法
- abstract 类中可以有abstract 方法
- abstract 类不能用new 运算符创建对象
- abstract 类的子类,必须重写父类的abstract 方法
- abstract 类的对象坐上转型对象
面对抽象编程
- 使用多态进行程序设计的核心技术之一是使用上转型对象。
- 即将abstract 类声明的对象作为其子类对象的上转型对象。
- 那么这个上转型对象就可以调用子类重写的方法。
面向抽象编程的目的是为了应对用户需求的变化,将某个类中经常因需求变化而需要改动的代码从该类中分离出去。面向抽象编程的核心是让类中每种可能的变化对应地交给抽象类的一个子类去负责,从而让该类的设计者不去关心具体实现,避免所设计的类依赖于具体的实现。
开-闭原则
让设计的系统对扩展开放,对修改关闭。
9. 接口与实现
接口
使用关键字 interface 来定义一个接口。
接口的定义和类的定义很相似,分为接口声明和接口体。
- 接口声明
interface 接口的名字
- 接口体
接口体中包含常量的声明(没有变量)和抽象方法两部分。
接口体中所有的常量的访问权限一定都是 public ,而且是static (允许省略public 、final和static 修饰符)
所有的抽象方法权限一定都是public (允许省略Public abstract 修饰符)
interface Printable{
public static final int MAX =100;
public abstract void add();
public abstract float sum(float x,float y);
}
- 实现接口
- 类实现接口
- 重写接口中的方法
- 接口的细节说明
抽象类既可以重写接口中的方法,也可以直接拥有接口中的方法。
接口加public 修饰: 可以被任何一个类实现
不加public 修饰:可以与该接口在同一包中的类实现。
同时,接口也可以用extends 继承。
- 接口回调
- 同类一样,接口也是Java 中一种重要的数据类型。
- 用接口声明的变量称为接口变量。
- 接口属于引用型变量,接口变量中可以存放实现该接口的类的实例的引用,即存放对象的引用。
可以把实现某一接口的类的创建的对象的引用赋值给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口方法。实际上,当接口变量调用被类实现的接口方法时,就是通知相应的对象调用这个方法。
注: 接口无法调用类中的其他的非接口方法。
小结
- 接口的接口体中只可以有常量和abstract 方法。
- 和类一样,接口也是Java 中一种重要的引用型数据类型,接口变量就可以调用类实现该接口的类的实例(对象)的引用。
- 当接口变量中存放了实现接口的类的对象的引用后,接口变量就可以直接调用类实现的接口方法,这一过程被称为接口回调。
- 和子类体现多态类似,由接口产生的多态就是指不同的类在实现同一个接口时可能具有不同的实现方式。
- 在使用多态设计程序时,要熟练使用接口回调技术以及面向接口编程的思想,以便体现程序设计中所提倡的“开-闭原则”。
10.内部类与异常类
java支持在一个类中定义另一个类,这样的类称为 内部类
而包含内部类的类称为内部类的外嵌类
内部类的类体中不可以声明类变量和类方法
外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员
内部类仅供它的外嵌类使用,其他类不可以使用某个类的内部类声明对象
匿名类
一个子类去掉类声明后的类体
- 匿名类可以继承父类的方法也可重写父类的方法
- 匿名类可以访问外嵌类中的成员变量和方法,匿名类的类体中不可以声明static 成员变量和static 方法
- 由于匿名类是一个子类,但没有类名,所以在用匿名类创建对象时,要直接使用父类的构造方法。
异常类
java使用throw 关键字抛出一个Exception 子类的实例表示异常发生。
try-catch 语句
用该语句来处理异常,将可能出现的异常放在try 部分
将发生异常后的处理放在catch 部分
各个catch 参数中的异常类都是Exception 的某个子类
表明try 部分可能发生的异常
这些子类之间不能有父子关系
否则保留一个含有父类参数的catch 即可
程序必须在try-catch 块语句中调用可能发生异常的方法,其中catch 的作用是捕获throw 关键字抛出的异常对象。
断言
一般用于程序不准备通过捕获异常来处理错误
assert 声明一条断言语句
当发生某个错误时,要求程序必须立即停止执行。
assert booleanExpression;
assert booleanExpression:messageException;
启用与关闭断言语句
java -ea mainClass
try-catch- finally
常用实用类
常量池: 常量池中的数据在程序运行期间再也允许改变
处理事件
- 事件源
- 监视器
- 需要一个对象对事件源进行监视,以便对发生的事件作出处理。
- 事件源通过调用相应的方法将某个对象注册为自己的监视器。
- 处理事件的接口
- 监视器自动调用被类重写的接口方法