Java面向对象程序设计——(二)
目录:
// 附加: 变量命名规则
第一章:类和对象
1.1 对象
1.2 类
1.3 Java是面向对象的语言
第二章:类的无参,带参方法
2.1 类的方法概述
2.2 变量的作用域
2.3 面向对象编程
2.4 JavaDoc注释
2.5 带参方法
2.6 深入理解带参方法
2.7 包
第三章:对象和封装
3.1用面向对象设计电子宠物系统
3.2通过创建对象实现领养宠物功能
3.3使用封装优化电子宠物系统的类
第四章:继承
4.1 继承
4.2 重写和继承关系中的构造方法
4.3 抽象类
4.4 final修饰符
第五章:多态
5.1为什么使用多态
5.2 什么是多态
第六章:接口
6.1 接口基础知识
6.2 接口表示一种能力
6.3 接口表示一种约定
第七章:异常
7.1 异常概述
7.2 异常处理
7.3 抛出异常
7.4 开源日志记录工具log4j
内容:
变量命名规则
序号 | 条件 | 合法变量名 | 非法变量名 |
1 | 变量必须以字母、下划线“_”或“$”符号开头 |
_myCar score1 $myCar graph1_1 |
*myvariable1 //不能以*开头 9variable // 不能以数字开头 variable% // 不能包含% a+b // 不能包含+ My Varible // 不能包含空格 t1-2 // 不能包括连字符 |
2 | 变量可以包括数字,但不能以数字开头 | ||
3 | 除了“_”或"$"符号以外,变量名不能包含任何特殊字符 | ||
4 | 不能使用Java语言的关键字,如int、class、public等 |
第一章:类和对象
1.Java的类模板
访问修饰符 返回值类型 方法名() {
// 方法体
}
访问修饰符:
访问修饰符 | 本类 | 同包 | 子类 | 其他包 |
private | √ | |||
默认 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
private: 成员变量和方法只能在其定义的类中被访问,具有类可见性。
默认 : 成员变量和方法只能被同一个包里的类访问,具有包可见性。
protected: 可以被同一个包中的类访问。被同一个项目中不同包中的子类访问。
public: 可以被同一个项目中的所有类访问,具有项目可见性,这是最大的访问权限。
2、类和对象的关系
类是对象的类型,对象是类的实例。
类是对象的类型,不同于Int类型,具有方法。类通过调用构造变为对象。
3、new关键字的3个作用
① 开辟空间,向jvm索要空间
② 创建对象
③ 调用方法
第二章:类的无参、带参方法
1、成员变量和局部变量
成员变量:类的方法可以直接使用该类定义的成员变量。如果其他类的方法要访问它,必须首先创建该类的对象,然后才能通过操作符“.”来引用。
局部变量:它的作用域仅仅在定义改变量的方法内,因此只有在这个方法中能够使用。
异同点:
①作用域不同。局部变量的作用域仅限于定义它的方法,在改方法外无法访问。成员变量的作用域在整个类内部都是可见的,所有成员方法都可以使用,如果访问权限允许,还可以在类外部使用成员变量。
② 初始值不同。对于成员变量,如果在类定义中没有给它赋初始值,Java会给它一个默认值,基本数据类型的值为0,引用类型的值为null。但是Java不会给局部变量赋初始值,因此局部变量必须要定义赋值后再使用。
③ 在同一个方法中,不允许有同名的局部变量。在不同的方法中,可以有同名的局部变量。
④ 局部变量可以和成员变量同名,并且在使用时,局部变量具有更高的优先级。
2、如何生成JavaDoc文档
在MyEclipse中选择“File”-------->"Export"选项,弹出“导出对话框”,选择“Java”菜单中的“JavaDoc”选项,提交即可。
3、定义一个不定项的带参数组
public int add(int...num){ int sum =0; for(int i = 0;i<num.length;i++){ sum = num[i]+sum; } return sum; }
4、如何声明包
语法:
package 包名;
Java中,包的设计与文件系统结构相对应。因此,在命名包时,要严格遵守以下编码规范。
①Java包的名字通常由小写字母组成,不能以圆点开头或结尾。例如,“.mypackage”是错误的包名。
②一个唯一包名的前缀通常是全部小写的ASCII字母,并且是一个顶级域名com、edu、gov、net或org,通常使用组织的网络域名的逆序。例如,如果域名为jbit.cn,我们可以声明包为
package cn.jbit.mypackage;
③包名的后续部分依不同机构各自内部的规范不同而不同。这类命名规范可能以特定目录名的组成来区分部门、项目、机器或注册名。例如:
package cn.jbit.research.powerproject;
部门名 项目名
第三章:对象和封装。
1、类的成员包括:类的成员变量和成员方法,构造方法,代码块。
2、类(Class)和对象(Object)是面向对象中的两个核心概念。
3、Java中使用final关键字修饰常量。并且常量名通常为大写。
final String SEX_MALE=“Q仔”; final String SEX_FEMALE="Q妹";
问题1:如果想让企鹅类不能被其他类继承,不允许再有子类,则应该如何实现呢?
可以通过给Penguin类添加final修饰符来实现。
final Class Penguin{ } class SubPenguin extends Penguin{// 此行出现错误 }
问题2:如果企鹅类可以有子类,但是它的print()方法不能再被子类重写,则应该如何实现呢?
可以通过print()方法添加final修饰符来实现。
class Penguin { public final void print(){} } class SubPenguin extends Penguin{ public void print(){} // 此行出现错误 }
问题3:如果企鹅类可以有子类,但是增加一个居住地属性home,规定只能取值“南极”,则应该如何实现呢?
通过给home 属性添加final修饰符来实现
public class Penguin{ final String home ="南极"; // 居住地 public void setHome(String name){ this.home = home; // 错误,home不可以再次赋值 } }
常见错误:
class Dog{ String name; public Dog(String name){ this.name = name; } } class Test{ public static void main(String[] args){ final Dog dog = new Dog("欧欧"); dog.name = "美美"; // ① dog = new Dog("丫丫"); // ② } }
①出代码是正确的。②是错误的。使用final修饰引用型变量,变量不可以再指向另外的对象,所以②是错误的,但是所指对象的内容是可以改变的,所以①是正确的。
使用final修饰引用型变量时,变量的值是固定不变的,而变量所指向的对象的属性值是可变的。
4、构造方法及其重载
如果同一个类中包含了两个或两个以上的方法,它们的方法名相同,方法参数的个数或参数类型不同,则称该方法被重载了。,这个过程称为方法重载。成员方法和构造方法都可以进行重载。
5、static修饰符
static可以用来修饰属性,方法和代码块。static修饰的变量属于这个类所有。即由这个类创建的所有对象共用同一个static变量。通常把static修饰的属性和方法称为类属性(类变量)和类方法。
示例1:
StaticTest类
public class StaticTest { public int n = 0; public static int b = 0; public void addn(){ n = n +1; } public void addb(){ b=b+1; } }
Test类
public class Test1 { public static void main(String[] args) { StaticTest st = new StaticTest(); System.out.println("调用方法前的n:"+st.n); System.out.println("调用方法前的b:"+st.b); st.addb(); st.addn(); System.out.println("调用方法后的n:"+st.n); System.out.println("调用方法后的b:"+st.b); StaticTest st1 = new StaticTest(); System.out.println("新对象中的n:"+st1.n); System.out.println("新对象中的b:"+st1.b); } }
运行结果:
调用方法前的n:0
调用方法前的b:0
调用方法后的n:1
调用方法后的b:1
新对象中的n:0
新对象中的b:1
结论:
① 在加载类的过程中,完成静态变量的内存分配,再执行静态块,两者是在创建对象之前执行的。
② 类属性和类方法可以通过类名和对象名访问,示例属性和示例方法只能通过对象名访问。
③ 类方法只能访问类属性和其他类方法。
6、使用this调用重载的构造方法,只能在构造方法中使用,必须是构造方法的第一条语句。
public class Penguin { public String name; public String sex; public int health; public int love; public Penguin(String name,String sex){ this.name = name; this.sex = sex; } public Penguin(String name,int health,int love,String sex){ this(name, sex); // 调用重载的构造方法 this.health = health; this.love = love; } }
第四章:继承
1、抽象类:抽象类不能是静态类,不能用final修饰,抽象类可以有普通方法和属性,如果一个类继承抽象类,那么必须重写抽象类中的所有抽象方法。除非子类也是抽象类。
抽象类不能实例化,抽象类中只有方法声明,没有方法实现。
(一个类实现接口时,也必须实现接口中的所有抽象方法)
2、方法的重写:
在子类中对父类中同名的方法进行重写,成为方法的重写。
方法的重写满足如下要求:
①重写方法和被重写的方法必须具有相同的方法名。
②重写方法和被重写方法必须具有相同的参数列表。
③重写方法的返回值类型必须和被重写方法的返回值类型相同或是其子类。
④重写方法不能缩小被重写方法的访问权限。
3 、 重载和重写的区别和联系:
重载涉及同一个类中的同名方法,要求方法名相同,参数列表不同,与返回值类型,访问修饰符无关。
重写涉及的是子类和父类之间的同名方法,要求方法名相同,参数列表相同,返回值类型相同(或者是其子类),访问修饰符不能严于父类。
第五章:多态
1、子类转换成父类时的规则。
① 将一个父类的引用指向一个子类对象,称为向上转型,自动进行类型转换。
② 此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法。
③ 此时通过父类引用变量无法调用子类特有的方法。
第六章:接口
1、接口可以看作一种特殊的“抽象类”,抽象类利于代码复用,接口利于代码的扩展和维护。
2、说明:
① 接口的命名规则与类相同,如果修饰符是Public, 则该接口在整个项目中可见;如果省略修饰符,则该接口只在当前包可见。
② 接口中可以定义常量,不能定义变量。接口中的属性会自动调用public static final修饰,即接口中的属性都是全局静态常量。接口中的常量必须在定义时指定初始值。
puclic static final int PI = 3.14;
int PI = 3.14; // 在接口中,这两个定义语句效果完全相同
int PI; // 错误,在接口中必须指定初始值,在类中会有默认值。
3、接口中的属性都是全局静态常量,接口中的方法都是全局抽象方法,接口中没有构造方法。
一个类如果实现了一个接口,则必须实现接口中的全部方法,否则必须将其定义为抽象类。
第七章:异常
1、抛出异常——throw
public class Person { private String sex="男"; public String getSex() { return sex; } public void setSex(String sex) throws Exception{ if("男".equals(sex)||"女".equals(sex)) { this.sex = sex; }else{ throw new Exception("性别必须是\"男\"或者\"女\""); } } }
public static void main(String[] args) throws Exception{ Person person = new Person(); person.setSex("Male"); }
2、throw和throws的区别:
① 作用不同:throw用于在程序中抛出异常;throws用于声明在该方法内抛出了异常。
② 使用的位置不同:throw位于方法体内部,可以作为单独语句使用;throws必须跟在方法参数列表的后面,不能单独使用。
③ 内容不同: throw抛出一个异常对象,而且只能是一个;throws后面跟异常类,而且可以跟多个异常类。
3、自定义异常
自定义异常一般有如下几个步骤:
① 定义异常类,并继承Exception或者RuntimeException,前者为Checked异常,后者为运行时异常。
② 编写异常的构造方法,并继承父类的实现。常见的构造方法有四种形式。参见示例。
③ 实例化自定义异常对象,并在程序中使用throw抛出。
/** * 异常类 * */ public class GenderException extends Exception { // 构造方法1 public GenderException(){ super(); } public GenderException(String message){ super(message); } public GenderException(String message,Throwable cause){ super(message,cause); } public GenderException(Throwable cause){ super(cause); } }
/** * Person * */ public class Person { private String sex; public String getSex() { return sex; } public void setSex(String sex) throws GenderException{ if("男".equals(sex)||"女".equals(sex)) { this.sex = sex; }else{ throw new GenderException("性别必须是\"男\"或者\"女\""); } } }
/** * 測試類 * */ public class Test { public static void main(String[] args) { Person person = new Person(); try { person.setSex("Male"); } catch (GenderException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行结果: