一、面对对象编程的三个特性
- 封装性:经数据和对数据的操作封装在一起。通过抽象,从实例中抽取共同性质形成一般概念,例如类。
- 继承:子类可继承父类的属性和行为,继承父类所具有的数据和数据上的操作,同时增添子类独有的数据和数据上的操作。
- 多态:一是操作名称的多态,多个操作具有相同名字,这些操作所接受的消息必须不同;二是和继承有关的多态,同意操作被不同对象调用时产生不同行为。
二、类声明
- 类是JAVA程序的基本要素,JAVA应用程序有若干类组成,类声明的变量为对象变量。
- 类的定义两部分:类声明、类体
class 类名 { //class为关键字,用来定义类,类名要符合标识符规定 类体内容 }
三、类体
- 类使用类体来描述所抽象出的属性和行为。
- 类体的内容:变量的声明、方法的定义。
四、成员变量
- 所声明的变量成为成员变量和域变量。
- 类型:基本类型、引用类型(数组、对象、接口)。
class Factory { float [] a; Workman zhang; //zhang是Workman类声明的变量,即对象 } class Workman { double x; }
- 有效范围:在整个类中都有效。
五、方法
- 方法返回的数据类型可以是JAVA中任意一种数据类型。
- 方法体内可以对成员变量和方法体内声明的局部变量进行操作。
- 局部变量与声明位置有关,从声明位置之后开始有效。
- 如果局部变量和成员变量的名字相同,那么成员变量被隐藏,在该方法内暂时失效。若还想用该成员变量,则必须使用关键字this。
class Tom { int x = 10,y; void f() { int x = 5; y = x+this.x; //y得到的值是15 } }
- 成员变量有默认值,局部变量没有默认值。使用局部变量前,必须初始化局部变量值。
- 对成员变量的操作只能放在方法中。
class A { int a; float b; a = 12; //非法,这是赋值语句(不是变量声明,只能出现在方法中) b = 12.56f; //非法 }
六、构造方法
- 用类声明对象后,必须创建对象,即为声明的对象分配所拥有的变量。
- 构造方法是类中一种特殊方法,程序用类创建对象时,需使用它的构造方法。
- 构造方法:与所在类的名字完全相同,而且没有类型。
- 一个类中可以有多个构造方法,但必须保证它们参数不同。
- 若类中没有编写构造方法,系统会默认一个构造方法,此方法无参数,且方法内无语句。
class Point { int x,y; Point() { //是构造方法 x = 1; y = 1; } void Point(int a,int b) { //不是构造方法(该方法的类型是void) x = a; y = b; } int Point() { return 12; } }
七、创建对象
- 对象声明:类名 对象名;
- 为声明的对象分配变量:使用new运算符和类的构造方法为声明的对象分配变量,即创建对象。
- new运算符的作用:一是为变量分配内存。二是计算出引用的值(该值代表成员变量内存位置及相关重要信息),即表达式new XiyoujiRenwu()是一个值,赋值给对象。
- nwe运算符只能和类的构造方法进行运算,运算的最后结果是一个十六进制的数,这个数是对象的引用。
- 对象引用存在于栈中,对象的实体存在堆中。
八、使用对象
- 对象操作自己的变量:对象的变量是对象的实体,对象通过使用点运算符“.”访问自己的变量,格式为:对象.变量;
- 对象调用类中的方法:对象.方法;
- 体现封装:当对象调用方法时,方法中出现的成员变量就是指分配给该对象的变量。
- new XiyoujiRenwu()为一个匿名对象,可以用“.”来访问自己的变量,但要尽量避免使用。
九、对象的引用和实体
- 避免使用空对象。
- 一个类声明的两个对象如果具有相同的引用,二者就具有完全相同的变量。
- 垃圾收集:若某个实体是否已不再被任何对象所拥有,就释放该实体占有的内存。
- JAVA不像C++有类的析构方法,会自动释放内存。
十、类与程序的基本结构
- JAVA应用程序有一个主类,即含有main方法的类,JAVA应用程序从main方法开始执行。
- 若应用程序主类的源文件和其他源文件在同一目录中,也可以只编译主类源文件,JAVA系统会自动先编译主类需要的其他源文件。
- JAVA程序的类既可以存放在一个源文件中,也可以存放在不同源文件中。
- javac *.java可编译该目录下的全部源文件。
十一、参数传值
- 在JAVA中,方法的所有参数都是“传值”的。
- JAVA的引用型数据有:数组、对象、接口。
- 可变参数:使用“...”表示若干参数,这些参数类型必须相同,且最后一个参数必须是方法参数列表中最后一个参数。
public void g(double a,int ... x)
public void method(int ... x,int y) //×错误,最后一个参数y不是可变参数x所代表的参数之一
- 参数代表可以通过下标运算来表示参数列表中具体参数:x[0]、x[1]、...、x[m-1]来表示第1至m个参数。x.length表示参数个数。
- 对于可变参数,JAVA提供增强for语句。
public int getSum(int ... x) { int sum = 0; for(int param:x) { //for(声明循环变量:参数代表) sum = sum+param; } }
十二、对象的组合
- 如果对象a组合了对象b,那么对象a可以以组合的方式复用对象b的方法。
- 复用方法特点:一是对当前对象所包含对象的特点一无所知。二是当前对象随时可更换所包含对象。
- 如果A类的成员变量是用B类声明的对象,那么A和B是关联关系,在UML图中用实线连接。
- 如果A类的某方法的参数是用B类声明的对象或A类的某方法返回的数据类型是B类对象,那么A和B是关联关系,在UML图中用虚线连接。
十三、实例成员与类成员
- 成员变量分为:实例变量、类变量。
- 在声明成员变量时,用关键字static给予修饰的称作类变量。
class Dog { float x; //实例变量 static int y; //类变量 }
- 实例变量仅仅是对象相关联的变量,类变量是和该类创建的所有对象相关联的变量。
- 可以通过类名直接访问类变量。
- JAVA库提供的Arrays类,许多方法都是static方法。
import java.util.*; //Arrays类在java.util包中 public class Example4_11 { public static void main(String args[]) { Scanner scanner = new Scanner(System.in); int [] a = {12,34,9,23,45,6,45,90,123,19,34}; Arrays.sort(a); //将double类型数组按升序排序 System.out.println(Arrays.toString(a)); //返回a数组的字符串 System.out.println("输入整数,程序判断是否在数组中:"); int number = scanner.nextInt(); int index = Arrays.binarySearch(a,number); //判断number是否在数组a中,若是,返回索引;若不是,返回一个负数 if(index>=0) System.out.println(number+"和数组中索引为"+index+"的元素值相同"); else System.out.println(number+"不与数组中任何元素值相同"); } }
十四、方法重载
- JAVA中存在两种多态:重载、重写。
- 对象的行为通过类中方法来体现,行为的多态性就是方法的重载。
- 方法重载:一个类中,多个方法可具有相同名字,但这些方法的参数必须不同。
- 构造方法可以重载。
十五、this关键字
- this可以出现在实例方法和构造方法中,但不可以出现在类方法中。
- 在构造方法中使用this:
public class People { int leg,hand; String name; People(String s) { name = s; this.init(); //可以省略this,写成“init()” } void init() { leg = 2; hand = 2; System.out.println(name+"有"+hand+"只手"+leg+"条腿"); } public static void main(String args[]) { People boshi = new People("布什"); //创建boshi时,构造方法中的this就是对象boshi } }
- 类的实例方法可以调用类的其他方法,默认格式为:
this.方法 //“this.”可省略
类方法调用的格式为
类名.方法 //“类名.”可省略
- this不能出现在类方法中,类方法可通过类名直接调用,此时可能还没用任何对象产生。
十六、包
- 包:有效管理类的一个机制,目的是有效区分名字相同的类。
- package语句是JAVA源文件的第一条语句,指定类所在的包。包名可以是合法标识符,也可以由若干标识符加“.”分隔而成。
package sunrise; package sun.com.cn;
- 若省略了package语句,隐含地认为是无名包的一部分。
- 程序如果使用了包语句,例如:
package tom.jiafei;
则存储文件的目录结构中须包含:...\tom\jiafei,并要将字节码文件保存在此目录中。
- 可以进入tom\jiafei的上一层目录中编译源文件:
C:\1000> javac tom\jiafei\源文件
- 主类:必须到tom\jiafei的上一层目录中去运行:
C:\1000> java tom.jiafei.主类名
- JAVA语言不允许用户使用java作为包名的一部分
十七、import语句
- 作用:引入包中类和接口。
- java.lang是JAVA语言的核心类库,系统自动引入,无需再使用import语句。
- 如果引入整个包的类,会增加编译时间,但不影响程序运行性能。
- 如果不用impot语句,也可直接带包名使用:
java.util.Date date = new java.util.Date();
- 若想要引用自定义包中的类,则可更新classpath的值,指明包所在位置。
- 若不希望更新classpath,则需要把程序所使用包名所形成的目录放在同一个文件夹下。
- 有包名的类无论如何都不能使用无包名的类。
十八、访问权限
- 指对象是否能用“.”运算符操作自己的变量或通过“.”运算符调用类中的方法。
- 访问修饰限制符:private、protected、public,用来修饰成员变量和方法。
- 在编写类时,类中实例方法总是可以操作类中实例变量和类变量,类方法总是可以操作该类中类变量,与访问限制符无关。
- private:私有变量和私有方法,对象不能访问私有变量和私有方法。
- public:公有变量和共有方法,在其他同包和不同包类中都能通过对象名和类名来访问共有变量和共有方法。
- 友好变量和友好方法:不被访问修饰限制符所修饰,只能在同包的类中通过对象名和类名访问友好成员变量和友好方法。
- protected:受保护成员变量和受保护方法,不被访问修饰限制符所修饰,只能在同包的类中通过对象名和类名访问友好成员变量和友好方法。
- public类:可在任何另外一个类中使用public类创建对象。
- 友好类:在另外一个类中使用友好类创建对象时,保证它们在同一包中。
- 不能用private和protected修饰类。
- 访问权限由高到低排序:public、protected、友好的、private。
十九、基本类型的类封装
-
Double(double num); //创建double类型对象 doubleValue(); //返回该对象含有的double型数据
Character(char c); charVaule();
二十、对象数组
- 创建对象数组
Student [] stu; stu = new Student[10];
Student stu[] = new Student[10];
- 在使用对象数组前,应当创建数组所包含的对象
stu[0] = new Student();
二十一、JRE扩展与jar文件
- JAVA运行环境提供扩展(\jre\lib\ext),只要将类打包为jar格式文件,放入扩展中,程序就可以使用import语句使用扩展中的类了。
- 将同包的源文件编译。
- 编写一个清单文件:hello.mf(Manifestfiles)
Manifest-Version: 1.0 Class: moon.star.TestOne moon.star.TestTwo //包名+class文件名,以空格隔开 Created-By: 1.8 //jdk1.8
将此文件保存在包所在的目录中。(所有的冒号下面都要一个空格)
- 进入包所在目录,使用jar命令来生成Jerry.jar文件
jar cfm Jerry.jar hello.mf moon\star\TestOne.class moon\star\TestTwo.class
若包中只有class文件,也可以如下使用jar命令
jar cfm Jerry.jar hello.mf moon\star\*.class
- 将Jerry.jar文件复制到JDK安装目录的jre\lib\ext文件夹中。
- 此时,就可以用import语句引入Jerry.jar中的类了:
import moon.star.*; public class Use { public static void main(String args[]) { TestOne a = new TestOne(); a.fTestOne(); TestTwo b = new TestTwo(); b.fTestTwo(); } }
二十二、文档生成器
- 使用JDK提供的javadoc.exe来制作源文件类结构的html格式文档
javadoc Example.java
查看这些文档可知道源文件中类的组成结构。
- 也可以使用参数-d指定生成文档所在目录,如:
javadoc -d F:\gxy\book Example.java
二十三、静态块
- 类的字节码进入内存时,类中静态块会被立即执行:
class AAA { static { //静态块 System.out.println("我是AAA中的静态块!"); } } public class E3 { static { //静态块 System.out.println("我是最先被执行的静态块!"); } public static void main(String args[]) { AAA a = new AAA(); //AAA的字节码进入内存 System.out.println("我在了解静态(static)块"); } }
习题:
3.1
3.2
3.3
3.5
3.6
4
public class Test { public static void main(String args[]) { CPU cpu = new CPU(); HardDisk disk = new HardDisk(); PC pc = new PC(); cpu.setSpeed(2200); disk.setAmount(200); pc.setCPU(cpu); pc.setHardDisk(disk); pc.show(); } } class CPU { int speed = 0; void setSpeed(int m) { speed = m; } int getSpeed() { return speed; } } class HardDisk { int amount = 0; void setAmount(int m) { amount = m; } int getAmount() { return amount; } } class PC { CPU cpu; HardDisk HD; void setCPU(CPU c) { cpu = c; } void setHardDisk(HardDisk h) { HD = h; } void show() { System.out.println("硬盘速度为:"+cpu.getSpeed()); System.out.println("硬盘容量为:"+HD.getAmount()); } }