第4章 面向对象编程(一)
4.1 认识类和对象
1.定义一个类的语法如下:
Class 类名 {
所含变量定义;
}
类名不能是Java中的关键字,即名字可以由字母、下划线、数字或美元符号组成并且第一个字符不能是数字。
2.一般情况下,由类定义的“变量”不叫“定义变量”,而叫“实例化对象(Object)”。通过类实例化对象的最简单的语法如下:
类名 对象=new 类名();
说明:实例化还可以写成以下两句代码。
Customer zhangsan;
zhangsan=new Customer();
第一句相当于定义了对象zhangsan,它是一个Customer类型,这称为对象引用,但是还没有给其分配内存,该引用指向空值(null),如图:
第二句让zhangsan引用一个实际的对象,让其分配了相应内存,如图:
如果不用关键字new分配内存,该对象为空值(null),不能使用。
通过对象名使用成员变量的最基本的方法如下:
对象名.成员变量名
4.2 认识成员函数
1.最简单的成员函数,格式如下:
void 函数名称() {
函数内容;
}
注意:在类的内部,普通的成员函数可以直接使用同一个类中的成员变量,不需要加对象名,例如“System.out.println("name="+name);”
2. 加参数的成员函数,格式如下:
void 函数名称(类型1 参数1,类型2 参数2,......类型n 参数n) {
函数内容;
}
调用方法为“对象名.函数名(参数列表);”
注意:如果函数内部的变量和类中的成员变量重名,成员变量会被屏蔽,得不到正常效果。此时可以用“this.”来标识该变量属于类中的成员,而不是局部变量。
this表示本对象的引用,可以理解为“本对象自己”。
3.带返回类型的成员函数,格式如下:
void 函数名称(类型1 参数1,类型2 参数2,......类型n 参数n) {
函数内容;
return 和返回类型一致的某个变量或对象;
}
注意:“int abs(int a);”定义了函数abs,返回一个整数类型的值;
“int result=c.abs(-10);”表示调用该函数,将返回值存入result突变;
没有返回类型的函数也可以使用return,表示跳出该函数,但是不能return一个具体的值;
4.函数重载不能盲目地将函数名定义为一样,必须满足以下条件之一:
函数参数的个数不同;
函数参数的个数相同,类型不同;
函数参数的个数相同,类型相同,但是在参数列表中出现的顺序不同;
注意:函数重载也称静态多态
多态是面向对象编程的特征之一。多态,通俗来讲就是一个东西在不同情况下呈现不同形态。
4.3 认识构造函数
1.构造函数也是一种函数,但是定义时必须遵循以下原则:
函数名称与类的名称相同;
不含返回类型;
其使用方法如下:
类名 对象名=new 类名(传给构造函数的参数列表);
注意:当一个类的对象被创建时,构造函数就会被自动调用,可以在这个函数加入初始化工作的代码。在对象的生命周期中,构造函数只会被调用一次;
构造函数可以被重载,也就是说在一个类中可以定义多个构造函数。实例化对象时,系统根据参数的不同调用不同的构造函数;
在一个类中如果没有定义构造函数,系统会自己为这个类产生一个默认的构造函数,该函数没有参数,也不做任何事情。因此,只有在没有定义构造函数时才可以通过“类名 对象名=new 类名();”实例化对象。
如果用户自己定义了含有参数的构造函数,系统将不提供默认的构造函数。
第5章 面向对象编程(二)
5.1 静态变量和静态函数
1.注意:静态变量可以通过“对像名.变量名”来访问,例如:"zhangsan.bankName",也可以通过“类名.变量名”的方法访问,例如“Customer.bankName”,一般情况下推荐用“类名.变量名”的方法访问,而非静态变量是不能用“类名.变量名”的方法访问的。
从底层讲,静态变量在类被载入时创建,只要类存在,静态变量就存在,不管对象是否被实例化。
2.静态函数可以通过“类名.函数名”来访问,也可以通过“对象名.函数名”来访问。推荐用“类名.函数名”来访问。
注意:在静态函数调用时对象还没有创建,因此在静态函数中不能直接访问类中的非静态成员变量和成员函数,也不能使用关键字this。
3.静态代码块,格式如下:
static {
bankName="香港银行";
System.out.println("静态代码块执行");
}
当类被载入时静态代码块被执行,且只被执行一次,静态代码块经常用来进行类属性的初始化。
5.2 认识封装
1.实现封装有以下两个步骤:
将不能暴露的成员隐藏起来。实现方法是将该成员定义为私有的,在成员定义前加上修饰符private。
用公共方法暴露对该隐藏成员的访问,可以给函数加上修饰符public,将该方法定义为公共的。
注意:私有成员只能在定义它的类的内部被访问,在类的外部不能被访问;
一般情况下,可以将成员变量定义为private,通过public函数(方法)对其进行访问;
private和public都是访问区分符。
5.3 使用包
1.注意:在源代码中,“package chinasei;”表示该源文件中的所有类都位于包chinasei中;
在Java中,推荐包名字的字母小写;
在将类放入某个包中之后,包将会用专门的文件夹来表示;
如果要用命令行某个包中的类,必须首先到达包目录所在的上一级目录;例如:Java 包路径.类名;
使用命令行编译一个.java文件,在默认情况下不会生产相应目录;
编写一个类,编译成.class文件之后任意放在一个目录下,这并不等于就将该类放在包中;
2.注意:如果一个包中的类很多,可以用“import 包名.*”导入包中所有类;、
5.4 使用访问控制修饰符
1.成员的访问控制修饰符其特征如下:
private类型的成员只能在定义它的类的内部被访问;
default类型的成员可以在定义它的类的内部被访问,也可以被这个包中的其他类访问;
protected类型的成员可以在定义它的内部被访问,也可以被包内、包外的所有其他类访问;
从开放的程度上讲,private<default<protected<public
注意:如果将一个类定义为public类,类名和文件名必须相同,因此在一个.java文件最多只能有一个public类。
5.5 使用类种类
1.类种类,顾名思义是在类中定义了类,也称为内部类;
注意:内部类中的成员只在内部类范围内才能使用,外部类不能像使用自己的成员变量一样使用它们;
如果在内部类中使用this,仅代表内部类的对象,因此也只能应用内部类的成员;
第6章 面向对象的编程(三)
6.1 使用继承
1.在Java中,被继承的类称为父类、基类或超类,与之对应的类称为子类或派生类。继承是通过关键字extends实现的,格式如下:
Class 子类 extends 父类 {}
2.注意:如果一个成员要被子类继承之后才能使用,这个成员不能是private类型,因为私有的成员不能再类的外部使用,当然也不能被子类使用。一般情况下,成员变量定义为proteced类型,成员函数定义为public类型;
Java不支持多重继承,一个子类只能有一个父类;
在Java中可以有多层继承,如:A继承了B,B又继承了C。此时相当于A间接地继承了C。
从本质上讲,子类继承父类之后实例化子类对象地时候,系统会首先实例化父类对象,调用的是父类没有参考的构造函数;若父类构造函数有参考,系统必须要求在实例化父类对象时传入参数;
3.注意:“super(title);”必须写在子类构造函数的第一句,传入的参数必须和父类构造函数中的参数列表类型相匹配;
6.2 成员的覆盖
1.如果子类中的函数定义和父类相同,最后调用时是调用子类的方法,称为覆盖或重写(Override)
注意:将Override和Overload相区别;
如果在子类中定义了一个名称和参数列表与父类相同的函数,但是返回类型不同,此时系统会报错;
在重写时,子类构造函数的访问权限不能比父类更加严格;
在覆盖的情况下,如果一定要在子类中调用父类的成员函数,可以使用关键字super,调用方法是“super.函数名”;
2.成员覆盖的作用:在不改变源代码的情况下能够对一个模板的功能进行修该;
6.3 使用多态
1.函数重载也是一种多态,称为静态多态。
2.函数传入的形参可以是父类类型,而实际传入的可以是子类对象;
函数的返回类型是父类类型,而实际返回的可以是子类对象。
3.子类类型对象转换成父类类型对象:无须转换就可以赋值给父类引用;
父类类型对象转换成子类类型:需父类类型对象原来是某一个子类类型的对象,则可以转换成相应的子类类型对象,此时使用强制类型转换即可;
可以使用instanceof操作符进行对象类型的判断,格式为“对象名 instanceof 类名”。
6.4抽象类和借口
1.在函数定义前加上abstract,则该函数为抽像函数;
含有抽象函数的类称为抽象类,抽象类必须用abstract修饰;
注意:抽象类不能被实例化;
抽象函数必须被重写,除非子类也是抽象类;
在抽象类中可以含有普通成员函数;
2.如果一个抽象类中的所有函数都是抽象的,也可以定义为“接口(inferface)”
在“继承接口”的情况下一般有另一中说法,叫“实现(implements)借口”,子类也称为实现类;
说明:接口中的方法不需要专门指明abstract,系统默认其为抽象函数,在接口中只能包含常量和函数;
接口中的成员函数默认都是public访问类型,成员变量默认是用public static final标识的,所以接口中定义的变量是全局静态常量;
接口可以通过extends继承另一个接口,类通过关键字implements来实现一个接口;
一个类可以在继承一个类的同时实现一个或多个接口,多个接口用逗号隔开,格式如下:
Class 子类 extends 父类 implements 接口1,接口2,...... {}
关键字extends必须位于关键字implements之前。
6.5 关键字final和Object类
1.用final修饰一个类,该类不能被继承;
用final修饰一个函数,该类在被子类继承的情况下,该函数不能被重写;
用final修饰一个成员变量,该成员变量不允许被改变,即不允许被重新赋值(哪怕是同一个值)。
注意:final成员变量必须在声明时或在构造函数中显示赋值才能使用。
2.在Java中定义一个类时,如果没有用extends明确标明直接父类,那么该类默认继承Object类,因此Object类是所有类的父类,或者说Java中的任何一个类是Object的子类。