您的位置:首页 > 职场人生

黑马程序员——面向对象

2015-04-08 08:44 141 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

< 今日心情 >塞满电池加上酱油,fighting!

一、 面向对象的概念

1.面向对象是一种思想

一个小孩的诞生,都会有哪些属性呢?

姓名(小名):狗蛋
生日:某年某月某日(某时)
动作(方法):哭

基本上,不管李家生了个小孩,还是孙家生了个,我们都会去做这些动作,这个就是面向过程的。

面向过程:

强调的是功能行为。

现在我们不这么做了。我们把这些过程封装起来形成一个具有属性和功能的类,每次诞生一个小孩只需一个命令调用这个类来创建出一个对象(具体过程交由jvm来实现),那么这个对象就有了这些功能和属性,我们只需要对这个对象进行操作即可。这就是面向对象思想。

面向对象:

将功能封装进对象,强调具备了功能的对象。

面向对象和面向过程都是一种思想,面向对象是基于面向过程而言的。

2.面向对象特点

是一种符合人们思考习惯的思想;

可以将复杂的事情简单化;

将程序员从执行者转换成了指挥者;

完成需求时:

先要去找具有所需的功能的对象来用;

如果该对象不存在,那么创建一个具有所需功能的对象;

这样简化开发并提高复用。

3.面向对象开发,设计,特征

开发的过程:

其实就是不断的创建对象,使用对象, 指挥对象做事情。

设计的过程:

其实就是在管理和维护对象之间的关 系。

面向对象的特征:

封装(encapsulation)

继承(inheritance)

多态(polymorphism)

二、 类和对象的关系

1.类与对象

李家生了一个小孩,叫狗蛋,要想创建这个对象就要有描述小孩的类。孙家又生了一个小孩,叫臭蛋,难道还要定义一个臭蛋的类吗?

姓名这个属性是该类对小孩的描述,至于具体叫什么就不管了,那是对象要做的事。

那么类和对象到底有什么关系呢?

其实类就是:对现实生活中事物的描述。

对象是:与描述相符合的一个实实在在的个体。

创建对象就是将描述具体化,细致化,就是将类中的属性赋予具体的值。

注:不能单独的为了建造一个汽车去建造一个汽车厂,同样不能为了实现一个或一些功能而单独定义类,类是对有共性属性和方法的事物的描述。

2.类的定义

类是事物的描述,描述的就是事物的属性和行为。
定义类其实就是在定义属性和行为。
理所当然,定义在类中的属性和行为都是该类的成员,属性就是成员变量(类中定义的变量),行为就是成员函数(类中定义的函数)。

类中的变量有成员变量和局部变量。
成员变量:

成员变量定义在类中,在整个类中都可以被访问。

成员变量随着对象的建立而建立,存在于对象所在的堆内存中。

成员变量有默认初始化值。

局部变量:

局部变量只定义在局部范围内,如:函数内,语句内等。

局部变量存在于栈内存中。

作用的范围结束,变量空间会自动释放。

局部变量没有默认初始化值。

注:在函数中定义了与成员变量相同的局部变量,如果不加描述,在该函数中访问和修改的都是局部变量,对应的成员变量与函数操作无关。

        在一个叫狗蛋小孩抱着一个叫狗蛋的小狗,小狗的死活对小孩并无关系。

2.创建对象

class Baby//定义一个描述小孩的类
{
String name;//成员变量,对小孩姓名的描述
String birth;
public void ku()//成员函数,小孩会哭
{
System.out.print("wawa");
}
public void dogOver()//成员函数,小孩会哭
{
String name="狗蛋";//局部变量,小狗的名字
System.out.println(","+name+"死啦!");
}
}

class Test
{
public static void main(String[] args)
{
Baby bb=new Baby();//创建一个描述了小孩的类的对象
bb.name="gou dan";//给这个孩子命名
bb.birth="2014.10.01";//记录孩子的出生日期
bb.ku();//让这个小孩哭一次
bb.dogOver();//因为小狗死啦
System.out.println("这个孩子叫:"+bb.name);//查看小孩的姓名
}
}




对象在内存中的结构:



只要是个小孩他都会哭,现在我只想听听这种哭声怎么办?(好邪恶啊!)

可以这么做:new Baby.ku();

这就是匿名对象及调用。单独匿名一个对象一般没有意义。

匿名对象是对象的简写形式。

匿名对象使用情况:

当对对象方法仅进行一次调用的时;

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

三、 封装

是指隐藏对象的属性和实现细节,仅对外提供 公共访问方式。

小孩哭都是有原因的,环境原因或者生理原因都会造成小孩哭,所以对象外部不需要单独访问小孩的哭行为。
只需要用private修饰这个哭方法一下就可以了,这也是一种封装。

class Baby//定义一个描述小孩的类
{
String name;//成员变量,对小孩姓名的描述
String birth;
private void ku()//成员函数,小孩会哭
{
System.out.print("wawa");
}
public void dogOver()//成员函数,小孩会哭
{
String name="狗蛋";//局部变量,小狗的名字
ku();
System.out.println(","+name+"死啦!");
}
}

class Test
{
public static void main(String[] args)
{
Baby bb=new Baby();//创建一个描述了小孩的类的对象
bb.name="gou dan";//给这个孩子命名
bb.birth="2014.10.01";//记录孩子的出生日期
//bb.ku();//让这个小孩哭一次
bb.dogOver();//因为小狗死啦
System.out.println("这个孩子叫:"+bb.name);//查看小孩的姓名
}
}

private :私有,权限修饰符:用于修饰类中的成员(成员变量,成员函数)。

私有只在本类中有效。

将ku()似有后,即使创建对象,通过对象也不能直接调用这个方法。
小孩也是个人,你不能随便让它哭。
想让他哭怎么办?杀掉他的狗狗,肯定能让他哭起来的(我又邪恶了,^_^)。

成员变量也可以似有化,外部想访问,只能通过类中的成员函数,没有提供这种成员函数外部就不能访问了。

四、 构造函数

小孩出生时往往都伴随着一个哭的动作,但是ku()已经被私有了,怎么办?
此时再通过“杀狗”来让小孩哭已经不现实,再者说,哭是伴随着出生而发出的动作,此时就需要一个构造函数。

class Baby//定义一个描述小孩的类
{
String name;//成员变量,对小孩姓名的描述
String birth;
Baby()//空参数的构造函数
{
ku();
}
private void ku()//成员函数,小孩会哭
{
System.out.print("wawa");
}
public void dogOver()//成员函数,小孩会哭
{
String name="狗蛋";//局部变量,小狗的名字
ku();
System.out.println(","+name+"死啦!");
}
}

class Test
{
public static void main(String[] args)
{
Baby bb=new Baby();//创建一个描述了小孩的类的对象
//bb.name="gou dan";//给这个孩子命名
//bb.birth="2014.10.01";//记录孩子的出生日期
//bb.ku();//让这个小孩哭一次
//bb.dogOver();//因为小狗死啦
//System.out.println("这个孩子叫:"+bb.name);//查看小孩的姓名
}
}




注:在创建对象的时候就完成的动作放在构造函数中。

构造函数的特点:

函数名与类名相同;

不用定义返回值类型;

不可以写return语句。

作用:

给对象进行初始化。

默认构造函数:在不给类添加构造方法时,类中有一个默认的构造空参数空内容的构造函数。

一个类中可以有多个构造函数,也就是说构造函数可以且必须重载

注意:一旦手动添加了构造函数,程序中的默认构造函数就不存在了。

构造代码块:

格式:一对独立的大括号。

作用:

给对象进行初始化。

对象一建立就运行,而且优先于构造函数执行。

和构造函数的区别:

构造代码块是给所有对象进行统一初始化,

而构造函数是给对应的对象初始化。

五、 this关键字

前面说过,局部变量的名字和成员变量的名字一样时,在方法中访问的是局部变量,那么如何让局部变量的值传递给同名的成员变量呢?

class Baby//定义一个描述小孩的类
{
String name="haha";//成员变量,对小孩姓名的描述
String birth;
Baby()
{
ku();
}
Baby(String name,String smallName)
{
System.out.println("姓名:"+name);//验证访问name变量到底是局部位置那个还是成员位置的那个
name=smallName;//改变name的值
this.name=name;//将局部变量的值赋值给成员变量
}
private void ku()//成员函数,小孩会哭
{
System.out.print("wawa");
}
public void dogOver()//成员函数,小孩会哭
{
String name="狗蛋";//局部变量,小狗的名字
ku();
System.out.println(","+name+"死啦!");
}
}

class Test
{
public static void main(String[] args)
{
Baby bb=new Baby("张三","狗蛋");//创建一个描述了小孩的类的对象
//bb.name="gou dan";//给这个孩子命名
//bb.birth="2014.10.01";//记录孩子的出生日期
//bb.ku();//让这个小孩哭一次
//bb.dogOver();//因为小狗死啦
System.out.println("这个孩子叫:"+bb.name);//查看小孩的姓名
}
}




似乎this可以区别同名的局部变量和成员变量,这是为什么呢?

this:就代表本类的对象;代表它所在函数所属对象的引用。

其实就是在对哪个对象操作就代表了哪个对象。

在构造函数中可以使用this()来调用其他重载的构造函数,参数的多少和类型与被调用者一致。
如:

class Baby//定义一个描述小孩的类
{
String name="haha";//成员变量,对小孩姓名的描述
String birth;
Baby()
{
ku();
}
Baby(String name,String smallName)
{
this();
System.out.println("姓名:"+name);
name=smallName;
this.name=name;
}
private void ku()//成员函数,小孩会哭
{
System.out.println("wawa");
}
public void dogOver()//成员函数,小孩会哭
{
String name="狗蛋";//局部变量,小狗的名字
ku();
System.out.println(name+"死啦!");
}
}

class Test
{
public static void main(String[] args)
{
Baby bb=new Baby("张三","狗蛋");//创建一个描述了小孩的类的对象
//bb.name="gou dan";//给这个孩子命名
//bb.birth="2014.10.01";//记录孩子的出生日期
//bb.ku();//让这个小孩哭一次
//bb.dogOver();//因为小狗死啦
System.out.println("这个孩子叫:"+bb.name);//查看小孩的姓名
}
}




注意:构造函数间调用,this必须放在构造函数的第一行。

this的应用:

当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。

但凡本类功能内部使用了了本类对象,都用this表示。

六、static关键字

在对事物进行描述时往往会有一些通用的属性值,比如描述一个圆的时候,π一样的。
小孩也有这样的值,比如:两个胳膊两条腿,一个脑袋一张嘴
这个时候我们用static来修饰这些变量或方法。

被修饰后的成员具备以下特点:

随着类的加载而加载

优先于对象存在

被所有对象所共享

可以直接被类名调用

注意:

静态方法只能访问静态成员

静态方法中不可以写this,super关键字

主函数是静态的

访问被static修饰的成员:

类名.被static修饰的变量名

类名.被static修饰的函数名

七、static关键字的应用

static修饰构造函数

单例设计模式:

禁止外部创建对象。

自身提供一个本类对象给外部使用。

保证了本类对象的唯一性。

class Baby//恶汉式
{
String name;
private static Baby bb = new Baby();//先创建对象
private Baby()
{
}

public static Baby getBaby()
{
return bb;
}
}

class SingleDemo
{
public static void main(String[] args)
{
Baby bb1=Baby.getBaby();
bb1.name="gou dan";
Baby bb2=Baby.getBaby();
bb2.name="çu008Bu0097ču009Bu008B";
System.out.println("bb1:"+bb1.name);
System.out.println("bb2:"+bb2.name);
}
}
class Baby//懒汉式,多线程不安全
{
String name;
private static Baby bb = null;
private Baby()
{
}

public static Baby getBaby()//调用的时候创建对象
{
if(bb==null)
Baby.bb=new Baby();
return bb;
}
}

class SingleDemo
{
public static void main(String[] args)
{
Baby bb1=Baby.getBaby();
bb1.name="gou dan";
Baby bb2=Baby.getBaby();
bb2.name="狗蛋";
System.out.println("bb1:"+bb1.name);
System.out.println("bb2:"+bb2.name);
}
}
class Baby//懒汉式,多线程安全
{
String name;
private static Baby bb = null;
private Baby()
{
}

public static Baby getBaby()
{
if(bb==null)
{
synchronized(Baby.class)//加锁,多线程安全
{
if(bb==null)
Baby.bb=new Baby();
return bb;
}

}
}
}

class SingleDemo
{
public static void main(String[] args)
{
Baby bb1=Baby.getBaby();
bb1.name="gou dan";
Baby bb2=Baby.getBaby();
bb2.name="狗蛋";
System.out.println("bb1:"+bb1.name);
System.out.println("bb2:"+bb2.name);
}
}




static修饰代码块

静态代码块:随着类的加载而运行,只运行一次。

class Baby
{
static{
System.out.println("ha ha ha");
}
public void ku()
{
System.out.println("wawawa");
}
}
class StaticDemo
{
public static void main(String[] args)
{
Baby bb=new Baby();
//bb.ku();
Baby bb2=new Baby();
bb.ku();
bb2.ku();
}
}


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