您的位置:首页 > 编程语言 > Java开发

Java 面向对象 第一部分(封装)

2013-09-14 21:43 190 查看
Java面向对象
一.  面向对象的概述

面向对象是一种思想,是相对面向过程而言的。它把现实生活中存在的每一个事物当成对象。每一个对象都有自己的特征和行为,java将对象的特征描述为属性,将行为描述为功能,并将属性和功能进行封装。强调了具备属性和功能的对象,主体是对象。当我们需要完成某项功能时,就可以直接使用或指挥相关的对象去完成。对于指挥者来说,它只需要知道结果,不关注过程,操作更加简单方便,所以在开发中,我们主要是明确对象,建立对象,找对象使用,维护对象关系。

面向对象的简化理解:

1.     面向对象是面向过程而言的,且基于面向过程。

2.     面向对象是一种思想。

3.     面向对象将功能和数据封装进对象,强调了具备功能的对象,主题是对戏那个,将过程简化。

4.     在实际开发中,以对象为核心,先明确好对象,再实现具体功能,或者可以使用已经有的对象,简单概括就是找对象,建立对象,使用对象。维护对象的关系。

5.     面向对象的三个特征:封装行、继承性、多态性。

二.  类与对象关系

1.     类(class):类就是对现实生活中事物的描述。对象就是这类事物,实实在在存在的个体,类中封装了该类事物的属性和行为。
打个比喻,自然界肯定是先有猫、豹、虎这些动物的存在,科学中才有了对这类动物的一个总体描述,所以科学称这类动物为“猫科类”动物,所以人们一听说“猫科动物”就知道这类动物具备哪些特征,那些基本行为。而在Java中,也是利用事物特征,将客观事物抽象成为类,通过类来产生一个个具体的对象,所以Java中是现有类,然后才有对象,类是创建对象的模版,对象是类的一个具体实例。

2.     类的定义和对象的创建
其实定义类,就是在描述事物,就是在定义属性和行为。属性和行为共同成为类中的成员(成员变量和成员方法)。

类的定义包含两个部分,类的声明和类体,类体中封装了该类事物的属性(成员变量)和成员方法(行为)。
当使用new关键字创建一个对象时候,该对象就在java在堆内存中存在了。类类型变量指向对象。堆内存中的成员变量都有一个默认初始化值。

对象可以使用对象名.成员变量和对象名.成员方法来指挥调用。

 

 
注意:
如果一个java源文件中定义了多个类,那么这些类中最多只能有一个类是public的,换句话说,定义的多个类可以都不是public的。java程序的入口是main方法,所以被定为public的这个类一定是main方法的类,且这个类的名称要和文件名一直,因为虚拟机是要开始找main方法这个入口的。

 

定义类和对象的例子:

/*
*需求: 创建一个汽车类,汽车有品牌名,颜色,有价格,有速度,
*       定义出汽车具备的基本功能,如行驶,发出喇叭声音。
*/
package com.baseObject;
publicclass CarDemo
{
publicstaticvoid main(String[] args)
{
//创建了一个名字为byd和qq的对象。
Car byd =new Car("比亚迪" , 78000.0 , "红色" , 500.0);
Car qq = new Car("奇瑞" , 88000.0 , "黑色" , 550.0);
//对象调用run()方法和sound()方法。
byd.run();
qq.run();
byd.sound();
qq.sound();
}
}
//定义了一个汽车类,汽车具备品牌名、颜色、价格等属性,还具备行驶,响喇//叭的功能
class Car
{
private Stringname;
privatedoubleprice;
private Stringcolor;
privatedoublespeed;
public Car(String name ,double price , String color ,double speed)
{
this.name = name;
this.price = price;
this.color =color;
this.speed = speed;
}
publicvoid run()
{
System.out.println(this.name + "正在高速上嗖嗖的行驶....");
}
publicvoid sound()
{
System.out.println("叭叭...叭叭...");
}

}


3.     new关键字创建对象的过程

Car byd = new Car("比亚迪"
, 78000.0 , "红色"
, 500.0);

该句话都做了什么事情?

A.     因为new用到了Car.class.所以会先找到Car.class文件并加载到内存中。

B.     执行该类中的static代码块,如果有的话,给Car.class类进行初始化。

C.     在堆内存中开辟空间,分配内存地址。

D.    在堆内存中建立对象的特有属性。并进行默认初始化。

E.     对属性进行显示初始化。

F.      对对象进行构造代码块初始化。

G.    对对象进行对应的构造函数初始化。

H.    将内存地址付给栈内存中的byd变量。
三.  成员变量和局部变量

1.     成员变量:成员变量必须定义在类中,是该类事物的特征属性、数据。

A.    作用范围:作用于整个类中。

B.     内存中的位置:在堆内存中,因为对象的存在,才在内存中存在。

C.     初始化方式:随着对象的初始化而初始化,如果没有指定初始化值,那么在初始化时就赋上默认值,所以成员变量可以不赋值就直接参与运算。

2.     局部变量:定义在成员方法或者语句块中的变量。

A. 作用范围:作用于成员方法中,或者语句块。

B.内存中的位置:存在于栈内存中,随着函数的结束而消亡
C.随着方法的加载而加载进栈内存中,无初始化值,必须先赋值才能参与运算
四.  匿名对象

1.     含义:所谓匿名对象,就是创建的对象没有名字,即没有类的引用指向这个对象,使用new出来直接使用的对象,例如:

new Car("比亚迪" , 78000.0 , "红色" , 500.0).run();


2.     使用方式

A.     当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化,如果对一个对象进行多个成员调用,必须给这个对象起个名字。

B.     可以将匿名对象作为实际参数进行传递。

3.     生命周期:匿名对象在被使用一次,或者说被用来调用一个成员方法,当方法结束后,垃圾回收机制会将这个匿名对象作为垃圾回收,非匿名对象则不同了,它是在这个对象不在被使用,或随着主函数的结束而被回收。

封装性
一.  封装的概述

A.     定义:封装是指隐藏对象的属性和实现细节,仅仅对外提供了可见的公共的方法方式,或方法。

A.     将不需要或则不能对外提供的内容隐藏起来,进行封装。

B.     把属性都隐藏起来,对外提供一个接口(公共方法)对其访问和设置。
说明:

A.    私有仅仅是封装性的表现形式之一,如包也是一种封装形式。

B.     之所以对外提供访问方式,就是因为可以在访问方式中加入逻辑判断等语句,对访问的数据进行操作,提高了代码的健壮性。

二.  封装性的优点

1.     提高了代码的健壮性

2.     将变化隔离

3.     便于使用

4.     提高重用性

5.     提高安全性
 

三.  private关键字

1.     private关键字是一个权限修饰符。

2.     只能用于修饰成员变量和成员方法。

3.     被私有化的成员变量和成员方法,对外部是不可见的,只在本类中有效。

4.     我们可以将成员变量修饰成private,使其隐藏,但是可以在类中提供对应的setXXX(),getXXX()方法对这些成员变量进行访问和设置,提高了数据访问的安全性。

5.     当把类中的所有构造函数私有化后,代表着该类是不能创建对象的,因为在外部无法调用private修饰构造函数进行对象和成员变量的初始化,当然即使在类内部定义一个main()方法,在其里面依然不能创建对象,因为main()方法必须是静态的,静态的方法不能访问非静态的方法,而且构造方法不能被修饰为静态的。

package com.baseObject;
publicclass PrivateDemo
{
publicstaticvoid main(String[] args)
{
Person p =new Person();
p.setAge(0);
p.setName("Ansen");
System.out.println("姓名:"+ p.getName() + " 年龄:"+ p.getAge());
}
}
class Person
{
//将age和name进行私有化
privateintage;
private Stringname;
//对外提供一个可供用来设置年龄的方法,并对传入的年龄进行check,是否符合//规则
publicvoid setAge(int age)
{
if(age >= 130 || age < 0 )
{
System.out.println("年龄不合法。");
}
else
{
this.age = age;
}
}
//对外提供姓名设置的方法
publicvoid setName(String name)
{
this.name = name;
}
//对外分别提供获取年龄和获取姓名的方法。
public String getName()
{
returnname;
}
publicint getAge()
{
returnage;
}
}


方法与代码块

一.   main方法

我们从接触java到现在,时时刻刻都在用main()方法,那么main()方法是干什么用的呢?有什么含义呢?

public static void main(String [] args){....}

1.     main()方法,也称为主函数,是一个特殊的函数,这个函数都会定义在被public修饰的类中,public
static void main(String args[])写法是固定的。

2.     main方法修饰符即参数的含义

A.     public:代表该函数的访问权限是最大的。

B.     static:代表着主函数随着类的加载而加载,类存在这个主函数就存在了,以便执行主函数中的代码,因为一个独立的java应用程序的入口是main函数,必须在类加载的时候而存在。

C.     void:表示主函数没有具体的返回值,只是程序执行的入口,换句话说,启动或调用这个主函数的是虚拟机,总不能说返回一个值给虚拟机吧。

D.    main:不是关键字,但是是一个特殊的单词,可以给虚拟机识别作为程序入口的函数名。

E.     (String [] args)):函数的参数,参数类型是一个String类数组,元素为字符串。字符串类类型是数组,args是一个变量名,早期被写成arguments;如果改写成其他名称也是可以的,这个参数可以用来接收运行程序时用户设定的参数。

注意:可以重载主函数,但是虚拟机只识别固定格式的主函数,即 public
static void main(String [] args){....}。

二.  构造方法

1.     定义:构造方式一种特殊的方法,它的名字必须与它锁在类的名字完全相同,并且没有返回值类值,也不需要void关键字标识,但是可以有一个或者多个参数,也可以没有,也不能在构造函数中使用return关键字,构造方法用于对对象中的所有成员成员变量进行初始化,在创建对象时立即被调用,需要注意的,如果用户没有定义构造方法,java会自动提供一个默认的构造方法,用来实现成员变量的初始化。

2.     特点:

A.     函数名与类名相同

B.     不能定义返回类型,括号中的参数可以没有,也可以有多个。

C.     不可以写return语句

D.    构造函数总是伴随着new操作一起被调用。

E.     当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数,即:类名(){}。但当类中自定义了构造函数后,默认的构造函数就不存在了。也就是说,每一个类中一定含有一个构造函数。

F.      一个类中可以有一个或者多个构造方法存在,而多个构造方法存在是一重载的方式存在的。

3.     作用:给对象成员变量进行初始化

4.     构造方法和一般成员方法的区别

A.    构造函数时在对象一建立就运行,是给对象初始化的。且一个对象建立后,构造函数只运行一次。一般函数是对象调用才执行,是给对象添加对象具备的功能的。一般函数可以被该对象多次调用。

B.     一般函数是不能调用构造函数的,因为一般函数中不能定义this,而构造函数中可能存在this。

5.     何时使用构造方法

当分析事物时,该事物存在具备一些特性或行为,那么将这些内容定义在构造函数中。也就是说,一类事物一出现就应该存在的特性,这就需要构造函数对其进行初始化。

 

三.  构造代码块

1.     什么是构造代码块?
构造代码快是定义在类中,不能定义在方法中,是用一对花括号括起来的代码块,成为构造代码块,给对象进行初始化,对象一建立就运行,且优先于构造函数执行,即在构造函数前加载。

publicclass Person
{
privateintage ;
private Stringname ;
{
System.out.println("呜呜.....呜呜");//构造代码块,每个人生下来都会哭。
}
public Person(int age)
{
this.age =age;
}
public Person(int age , String name)
{
this(age);
this.name =name;
}
}


2.     与构造函数的区别

构造代码块是给所有对象进行统一初始化,是所有对象的共性初始化方式内容,如任何婴儿出生都要哭几声,构造函数是给对应的对象初始化,不同的对象有各自的特性,需要选择不同的构造函数初始化。

 

四.  this关键字

1.     定义:this表示当前对象(当前正在调用类中成员或构造方法的对象)。

2.     this关键字的特点

A.    this代表了本类的对象,即代表了它所在函数所属对象的引用,也就是说,哪个对象调用这个函数,this就代表哪个对象,也可以说当前正在调用类中成员或构造方法的对象。

B.     一般情况下,this都是被省略的,需要使用的时候才需加上。

3.     this的用法

A.    用于区分同名的局部变量和成员变量,也就是说当类中的某个方法中定义了一个局部变量,而这个局部变量和类中的某个成员变量同类型并且同名,那么这时我们要在局部访问或操作这个成员变量的时候,则肯定是操作局部的这个变量,可是我们实际的是想访问或操作成员变量,那么这时候我们可以用this.成员变量名的方法去区分访问。

 
class Person
{
privateintage = 24;
private Stringname ="Ansen";
//构造函数接收两个参数,这两个参数就是两个局部变量,
//当我们要将这两个局部变量的值赋给成员变量的时候,就要用
//this关键来对它们进行操作了。
public Person(int age , String name)
{
this.age = age;
this.name = name ;
}
}
B.     用于构造函数之间的调用

publicclass Person
{
privateintage ;
private Stringname ;
private Stringid;
public Person(int age)
{
this.age =age;
}
public Person(intage , String name)
{
this(age);//调用只有一个参数的构造方法为age赋值。
this.name =name;
}
public Person(int age , String name,String id)
{
this(age , name);//调用两个参数的构造方法为age和name赋值。
this.id = id;
}
}


注意:

1.     用于构造方法之间的调用,必须有一个构造方法是没有使用this关键字去调用其他构造方法的,否则就存在一个死循环调用的结果。

2.     而且还必须放在构造调用构造方法的第一行语句,否则编译失败

五.  static关键字

1.     定义:static关键字是一个修饰符,可以用来修饰成员变量,成员方法(不可以用来修饰构造函数),当成员变量或成员方法被static关键字修饰之后,表示它们是静态公有的,是属于类的,并不属于某个对象的。

2.     static的特点

A.     用来修饰成员变量和成员方法,当修饰为static之后,就多了一种调用方法,除了使用对象.成员之外,多了一种直接使用类名.成员的调用方式。

B.     当修饰成员变量和成员方法的时候,这些成员变量和成员方法会随着类的加载而别加载,在类或内存中的声明周期是最长的。

C.     因为static修饰的成员变量和成员方法是是随着类的加载而加载,所以会先于对象的存在,因为对象只有在类被加载之后,才能去创建对象,而此时类一加载还没有对象存在,所以是先于对象存在的。

D.    静态的成员变量和成员方法是被所有对象共享的,并不是属于某个对象,而是属于类的。

E.     可以通过类名称直接调用。

F.      静态方法只能调用静态的方法或静态的变量,因为非静态的是属于对象的,static修饰的成员变量和成员方法是是随着类的加载而加载,所以会先于对象的存在,因为对象只有在类被加载之后,才能去创建对象,而此时类一加载还没有对象存在,而非静态的方法是属于对象,如果此时没有对象,调用就会失败。

G.    static关键字不能用来修饰局部变量,因为局部变量所用范围是方法内部或者代码块中,而static是作用于整个类,是被所有对象共同访问的使用的,它是类加载时候就存在的,直到这个类不在被使用或则jvm退出时候才可能被垃圾回收机制回收,而局部变量是方法执行完毕,就会被回收,但是此时对象或类并没有使用完毕,静态的变量还存在。

H.    static修饰的成员是存放在内存的共享区(方法区,数据区)中

3.     静态常量
使用static和final修饰的变量就是常量,常量的值是不可以被修改的,静态常量不但不可以改变,而且是共享的。我们知道计算圆的周长面积体积等计算用的π的值是被明确固定下来的,那么我们如果在开发中,程式中要用到这个值,就可以将它定义为静态常量。

public class Math
{
...
public static final double PI = 3.14159265358979323846;//final将PI设置为不可再定义的常量
...
}


如果省略了static,PI就变成了一个实例常量,那么,每一个Math对象就都有自己的一个PI拷贝了,这样的话,对内存也是一种占用。
 

 

4.     静态变量

 
class Student
{
private String id;
private static String country ="china";
//获取id的访问器
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
}


以上就定义了一个静态变量,我们知道每一个学都有学号id,都已一个国籍,对于中国的学生来讲,没一个学生国籍都是中国,那么可以将过激country定义为静态变量,以便所有对象使用,这样每一个对象就不用去copy一份country到自己的堆内存中,减少了对内存的开销。

6.     静态方法
当方法被static修饰的时候,此方法是用类名.方法名的方式使用的,当然也可以用对象名.方法名,但是这样就会产生误解,会让别人以为这个方法是非静态的,这样就有些不合理了。但是静态方法有一点需要注意的是:静态方法只能访问静态成员,因此静态方法也就不能定义this和super等关键。

7.     静态的应用
当每个应用程序都有共同之处,可将其封装,提高其复用性。
需要注意的是:

A. 对象时用于封装数据的。

B.对数据的操作方法,若没用到方法中特有的数据,则无需创建对象而占用多余的内存。

8.     静态代码块
静态代码块是定义在类中的,不能定义在方法中,是使用static后面跟一对花括号的代码块,如下所示:

publicclass Person
{
privateintage ;
private Stringname ;
static
{
System.out.println("类加载完毕");//定义了一个静态代码块
}
public Person(int age)
{
this.age =age;
}
public Person(int age , String name)
{
this(age);
this.name =name;
}
}


静态代码块的特点:

A.      随着类的加载而被执行,而且优先与主函数执行

B.     只有在类被加载的时候执行一次,之后不在执行。

 

9.     静态的有点和缺点
好处 :对对象的共享数据惊醒单独空间的存储,节省空进。没必要每个对象中都要存储一份,可以直接被类名调用
弊端 :生命周期过长。访问出现局限性,因为静态只能访问静态。

class Student
{
private static String country = "CN";//因为国家是共有的,共享
private int id;
private static int nextId = 1;
//静态代码块
static
{
System.out.println("Hello");
}
public static String getCountry()
{
return country;
}
public int getId()
{
return id;
}
public void setId()
{
id = nextId;
nextId++;//前一个人获取id后,然后一个人获取下一个id时就加1
}
}

class StudentText
{
public static void main(String [] args)
{
Student st1 = new Student();
st1.setId();
System.out.println("st1'country = " + Student.getCountry() + "; st1id = " + st1.getId());
Student st2 = new Student();
st2.setId();
System.out.println("st2'country = " + Student.getCountry() + "; st2id = " + st2.getId());
}
}


六.  final关键字

1.     定义:译为最终。是java中的修饰符

2.     final关键字的特点:

A. 可以用来修饰变量(成员变量,局部变量,静态变量),可以用来修饰成员方法,但是不可以用来修饰构造方法,可以用来修饰类

B. 被用来修饰变量,表示这个变量的值将不能改变,是一个常量,只能赋值一次。
应用:当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字,方便于阅读,而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成,单词间通过_连接。
如:数学函数中的圆周率PI是一个固定值,在java中北定义为final的,是为了让程序更加
 public static final double PI = 3.141592654

C. 被用来修饰方法的时候,表示该方法不能被复写。

D. 被用来修饰类的时候,表示该类不能被继承,要防止被子类将本来功能复写。

E. 内部类定义在类中的局部位置上是,只能访问该局部被final修饰的局部变量。

F.抽象类和接口不能用final来修饰,即一个类不能既是最终类又是抽象类。

      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java 面向对象封装