第四章 类与对象
事物
属性: 事物的信息描述
行为: 事物的功能
类
成员变量: 事物的属性
成员方法 : 事物的行为
1.面向对象
1). 封装性
面向对象编程的核心思想之一就是将数据和对数据的操作封装结合在一起。通过抽 象,即从具体的实例中抽取出共同的性质形成一般的概念,比如类的概念。
将实物的属性和行为给出概念:类
类声明的变量(类的实例):对象
2). 继承
利用由已有的类创建新类的机制。子类继承父类的属性和行为,即继承其所有的数据和数据上的操作,同时可以添加子类独有的数据和数据上的操作。
3). 多态
- 操作名称的多态
即有多个操作具有相同的名字,但是这些操作所接受的消息类型必须不同。所谓操作名称的多态性是指向操作传递不同消息,以便让对象根据相应的消息来产生相应的行为。 - 与继承有关的多态
同一个操作被不同对象调用时可能产生不同的行为
2.类
类是创建对象的模板,没有类就没有对象
类的定义:
class{
类体的内容
}
类体=变量的声明+方法的定义
-
局部变量:在方法体中声明的变量和方法的参数叫做局部变量。局部变量在方法内有效,而且与其声明的位置有关。
-
成员变量:成员变量是定义在类中,方法体之外的变量。成员变量在整个类内都有效,其有效性与它在类体中书写的先后位置无关。成员变量又可以分为类变量和实例变量,后面细写。
3.构造方法
构造方法是一种特殊方法,它的名字必须与它所在的类的名字完全相同,而且没有类型。
允许一个类中编写若干个构造方法,但必须保证他们的参数不同,即参数的个数不同,或者是参数的类型不同。(这就是方法重载的意思)
需要注意的是如果类中没有编写构造方法,系统会默认该类只有一个构造方法,该默认的构造方法是无参数的,且方法体中没有语句。
-
如果类里定义了一个或多个构造方法,那么Java不提供默认的构造方法 。
-
需要特别注意的是,构造方法没有类型 。
4.创建对象
创建一个对象包括对象的声明和为对象分配变量两个步骤。
1.对象的声明
类的名字 对象名字;
2.为声明的对象分配变量
使用new运算符和类的构造方法为声明的对象分配变量。
创建对象 :类名 对象名=new 类名();
对象操作自己的变量:对象 . 变量;
对象调用类中的方法: 对象 . 方法;
这是构造和方法的实例:
5.参数传值
方法中最重要的部分之一就是方法的参数,参数属于局部变量,当对象调用方法时,参数被分配内存空间,并要求调用者向参数专递值,即方法被调用时,参数变量必须有具体的值。
1)传值机制:
在Java中,方法的所有参数都是“传值”的,也就是说,方法中参数变量的值是调用者指定的值的拷贝。
-
基本数据的传值
对于基本数据类型的参数,向该参数传递的值的级别不可以高于该参数的级别 -
引用类型参数的传值
当参数是引用类型时,“传值”传递的是变量中存放的“引用”,而不是变量所引用的实体
6.对象的组合
一个类可以把对象作为自己的成员变量,如果用这样的类创建对象,那么该对象中就会有其它对象,也就是说该对象将其他对象作为自己的组成部分,或者说该对象是由几个对象组合而成。
1)组合与复用
如果一个对象a组合了对象b,那么对象a就可以委托对象b调用其方法,即对象a以组合的方式复用对象b的方法。当前对象随时可以更换所包含的对象。
2)类的关联关系和依赖关系
- 关联关系
如果A类中 成员变量是用B类声明的对象,那么A和B的关系是关联关系。 - 依赖关系
如果A类中某个方法的参数 是用B类声明的对象或某个方法返回的数据类型是B类对象,那么A和B的关系就是依赖关系。
7.实例成员与类成员
1)成员变量细分为实例变量和成员变量。在声明成员变量时,用关键字static给予修饰的称作类变量,否则称作实例变量(类变量也称为static变量,静态变量)。
2)实例方法和类方法
1.不同对象的实例变量互不相同
2.所有对象共享类变量
3.对象调用实例方法 (实例方法可以被类创建的任何对象调用执行)
4.类名调用类方法(既可以被类创建的任何对象调用执行,也可以直接通过类名调用)
class Lader {
double 上底,高; //实例变量
static double 下底; //类变量
void 设置上底(double a) {
上底 = a;
}
void 设置下底(double b) {
下底 = b;
}
double 获取上底() {
return 上底;
}
double 获取下底() {
return 下底;
}
}
public class Example4_10 {
public static void main(String args[]) {
Lader.下底=100; //Lader的字节码被加载到内存,通过类名操作类变量
Lader laderOne=new Lader();
Lader laderTwo=new Lader();
laderOne.设置上底(28);
laderTwo.设置上底(66);
System.out.println("laderOne的上底:"+laderOne.获取上底());
System.out.println("laderOne的下底:"+laderOne.获取下底());
System.out.println("laderTwo的上底:"+laderTwo.获取上底());
System.out.println("laderTwo的下底:"+laderTwo.获取下底());
}
}
8.方法重载
前面提到过一下,再解释一遍,方法重载的意思是:一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同,即或者是参数的个数不同,或者是参数的类型不同。方法重载有什么意义呢?在公司里编程,有时候一个方法名,要用到很多次,而且每次跟每次的参数都不一样,而且这个方法名,特别适合某个业务(比如登录),这个时候你变成其他的方法名,对大家来讲都很别扭,这时候就用到重载的概念了
举个例子
class People{ //People类中,hello方法是重载方法
float hello(int a,int b) {
return a+b;
}
float hello(long a,int b) {
return a-b;
}
double hello(double a,int b) {
return a*b;
}
}
public class Example4_12{
public static void main(String args[]) {
People tom=new People();
System.out.println(tom.hello(10, 20));
System.out.println(tom.hello(10L, 20));
System.out.println(tom.hello(10.0, 20));
}
}
9.this关键字
this是Java的一个关键字,表示某个对象。this可以出现在实例方法和构造方法中,但不可以出现在类方法中。
(1)在构造方法中用this
this关键字出现在类的构造方法中时,代表使用该构造方法所创建的对象.
public class People{
int leg,hand;
String name;
People(String s){
name=s;
this.init(); //可以省略this,即将this.init();写成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
}
}
(2) 在实例方法中用this
- 实例方法必须只能通过对象来调用,不能用类名来调用。当this关键字出现实例方法中时,代表正在调用该方法的当前对象。
实例方法可以操作类的成员变量,当实例成员变量在实例方法中出现时,默认的格式是:
this.成员变量;
当static成员变量在实例方法中出现时,默认的格式是:
类名.成员变量;
class A{
int x;
static int y;
void f() {
this.x=100;
A.y=200;
}
}
- 类的实例方法可以调用类的其它方法,对于实例方法调用的默认格式是
this,方法; - 对于类方法的默认格式是
类名,方法;
class B{
void f() {
this.g(); //this.g() 就是当前对象调用方法g,也就是说,在某个对象调用方法f的过程中又调用了g方法
B.h();
}
void g();{
System.out.println("ok");
}
static void h() {
System.out.println("hello");
}
}
this不能出现在类方法中,这是因为,类方法可以通过类名直接调用。这时,可能还没有任何对象诞生。
10.包
包是JAVA语言中有效地管理类的一个机制。
包名的目的是有效的区分名字相同的类。不同Java源文件中两个类名字相同时,它们可以通过隶属不同的包来相互区分。
-
包语句
通过关键字package声明包语句package语句作为Java源文件的第一条语句, 为该源文件中声明的类指定包名。
package语句的一般格式为:
package 包名; -
有包名的类的存储目录
程序如果使用了包语句,如:
package tom.jiafei;
那么存储文件的目录结构中必须包含有如下的结构
…\tom\jiafei
如:
c:\1000\tom\jiafei
并且要将源文件编译得到的类的字节码文件保存在目录c:\1000\tom\jiafei中(源文件可以任意存放)。 -
运行有包名的主类
如果主类的包名是tom.jiafei,那么主类的字节码一定存放在…\tom\jiefei目录中,运行时必须到tom\jiefei的上一层(即tom的父目录)目录中去运行主类。
假设tom\jiefei的上一层目录是1000,那么,必须如下格式来运行:
C:\1000\java tom.jiafei.主类名
11.import 语句
一个类可能需要另一个类声明的对象作为自己的成员或方法中的局部变量,如果这两个类在同一个包中,当然没有问题。如果一个类想要使用的那个类和它不在一个包中,要使用import语句完成使命。下面解释一下import语句
(1)引入类库中的类
如果用户需要类库中的类就可以使用import语句,如:
import java.until.Date;
引入java.util包中的Date类 .
import java.util.*;
表示引入java.util包中所有的类
(2)引入自定义包中的类
用户程序也可以使用import语句引入非类库中有包名的类,如:
import tom.jiafei.*;
在用户程序所在目录下建立和包相对应的子目录结构,比如用户程序所在目录是C:\ch4,想使用import语句引入tom.jiafei包中的类,那么根据包名建立如下的目录结构:
C:\ch4\tom\jiafei
(3) Java中访问修饰符public、private、protect、default范围
看到一个比较好的总结,链接一下
转载自http://lvdairy.blogbus.com/logs/51747079.html
12.对象数组
如果程序需要某个类的若干个对象,比如Student类的10个对象,显然如下声明10个Student对象是不可取的:
Student stu1,stu2, stu3,stu4,stu5,stu6,stu7,stu8, stu9,stu10;
正确的做法是使用对象数组,即数组的元素是对象,例如:
Student [] stu;
stu = new Student[10];
需要注意的是,上述代码仅仅定义了数组stu有10个元素,并且每个元素都是一个Student类型的对象,但这些对象目前都是空对象,因此在使用数组stu中的对象之前,应当创建数组所包含的对象,例如: stu[0] = new Student();
class Student{
int number;
}
public class Example4_21 {
public static void main(String args[ ]) {
Student stu[] = new Student[10]; //创建对象数组
for(int i=0;i<stu.length;i++) {
stu[i]=new Student(); //创建Student对象
stu[i].number = 101+i;
}
for(int i=0;i<stu.length;i++) {
System.out.println(stu[i].number);
}
}
}