黑马程序员——Java基础——面向对象概述

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、什么是面向对象

   1、概念理解

        面向对象是相对面向过程而言,我们知道c语言就是一门面向过程的语言。面向过程是分析出解决问题的步骤,然后用一个一个函数实现,然后使用的时候拿来调用。而面向对象是把解决的问题根据一定的规则划分为多个独立的对象,然后调用对象的方法来实现问题的求解。

         举例:如把大象装进冰箱,对于C语言来说,解决问题分三步:打开冰箱,把大象塞进冰箱,关闭冰箱。而面向对象的思想,是这样,打开冰箱,关闭冰箱,是冰箱具备的特性,因此,把冰箱封装对象,打开和关闭是它的方法,要把大象塞进冰箱,只需调用冰箱的打开和关闭方法即可。我们是冰箱的指挥者。

    面向对象是一种思想,能让复杂的东西简单化,能让我们的角色转变,由执行者变为指挥者。

   那么怎么才能知道一件事情中有几个对象呢,并且对它们封装呢,可以用名字提炼法。

名词提炼法:把名词提炼出来封装成对象。

如:人开门,人和门是对象,开是一个行为。开的动作应该定义在哪个对象里呢?谁最清楚这个动作的原理,就定义在谁里面。

门是怎么开的,只有门最清楚。通过门轴和弹簧的物理作用,这在制造门的时候,就已经具备了。所以应该定义在门里面。

{

开门(门)

{

.();

}

}

{

   开()

    {操作门轴等;}

}


2、面向对象的特点

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

        2)可以将复杂的事情简单化

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

        4) 代码复用性很高

面向对象有三个特征:封装、继承、多态。

二、类与对象

  1、类与对象的关系

     类的定义:类是用来创建对象的模版,它包含被创建对象的属性和行为的定义。

如:我们印刷时,用的模版,字体都被描述在模版上。

    类是具体事物的抽象。定义类,就是在定义对象的属性和行为。而对象是类的一个个实体。

具体对象就是对应java在堆内存中用new建立实体。创建对象就是通过new操作符来完成,就是在堆内存中产生一个实体。

Person类的定义:

class Person

{

   String name;

   int  age;

  public String getName()

{

return name;

 }

}

而在主函数中,我们只要创建一个Person类的对象,就可以操作对象。

public static void main(String[]args)

{

  Person   person=new Person();

   person.name="zhangsan;//对对象的age属性进行修改操作

 String name=person.getName();//获取person对象的name属性

}

2、成员变量和局部变量的区别:

不同一:作用范围不同

成员变量作用于整个类中

而局部变量只作用在函数中,或者语句中

不同二:在内存中的位置不同

成员变量:在堆内存中,因为对象的建立,才在内存中被建立

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

不同三:成员变量有默认初始化值,整型变量默认初始化值为0,字符串初始化值为null,double变量初始化值为0.0

而局部变量没有初始化值,要参与运算必须进行手动赋值。

例如

class Car

{

  String color;

   int  num;

}

类中的color变量是成员变量,作用在类中,

类对象car c=new car(); c.color=“red”;

存在栈内存中。

也可以在类中写个主函数,主函数中创建一个类对象。这个叫做在本类中创建本类对象。

  3、匿名对象

匿名对象是对象的简化形式

匿名对象两种使用情况

1) 当对对象的方法仅进行一次调用的时候

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

例如主函数中

new car();

这就是一个匿名对象。也可以写

new car().num=5;

这个匿名对象一执行完就已经变为垃圾了。因为没有人会调用它。

调用方法,匿名对象有意义,而调用属性,匿名对象没有任何意义。

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

匿名对象使用方式二,可以将匿名对象作为实参进行传递。

三、封装

    1、定义

       封装是面向对象编程的核心思想,将对象的属性和行为封装起来,而将对象的属性和行为封装起来的就是类,类会对用户隐藏它的实现细节。

    实际开发我们要做的就是找对象用,没有对象,就创建对象并且维护对象之间的关系。类就是对具体抽象的描述,而对象就是这个类的实体,具体实现。 映射到java中,描述就是class定义的类。具体对象就是对应java在堆内存中用new建立实体。属性和行为共同成为类中的成员(成员变量和成员方法或成员函数)。创建对象就是通过new操作符来完成,就是在堆内存中产生一个实体。

   2、 封装的优点:

       a.将变化隔离

       b.便于使用

       c.提高重用性

       d.提高安全性

  3、 封装的原则:

      a.不要对外要提供的内容都隐藏起来。

      b.把属性都隐藏,对外提供公共方法对其访问。

 很简单,比如一个电脑机箱,把cpu,硬盘,主板都封装在机箱内,可以方便我们使用,但是如果对外不提供任何接口,我们也同样无法使用。

     函数就是代码中最小的封装体。

 4、封装方法

   private:私有。是一种权限修饰符,用于修饰类中的成员,包括成员变量和成员方法。是最常用的一种封装方式。

     class Person

{

   private int  age;

 }

注解:私有只在本类中有效。

 将age私有化以后,类以外的程序中,即使建立了对象,也无法直接访问到age成员,必须通过公共接口才能访问。私有成员只能被类中的方法直接访问。

 如:电脑机箱的公共访问接口。

          一般,实际开发中,几乎所有的成员变量都被私有化,对外提供get和set方法来对成员变量进行获取和设置。


 但是,我们谨记,封装不是私有,私有只是封装的一种表现形式而已,什么是封装呢?就是只要访问权限不在你的访问范围之内,都叫做封装,而私有只是封装权限的最小权限。

四、构造函数

   1、特点:

     函数名与类名相同;

      不用定义返回值类型;

     不可以写return语句;

 2、作用

   给对象进行初始化操作。

 3、当我们没有定义构造函数时,系统默认会定义个空参数的构造函数,里面什么也不执行。形如:Person(){}。但当我们自定义一个构造函数时,系统就不会帮我们定义默认构造函数了。多个构造函数被定义时,是以重载的形式出现的。


 4、构造函数与一般函数的区别:

   1)构造函数和一般函数在写法上有不同,在运行上也有不同。

   2)构造函数是在对象一建立就运行,给对象初始化。而一般方法是对象调用才执行,是给对象添加对象的功能。

   3)一个对象一旦建立,构造函数只运行一次。而一般方法可以被对象调用多次。

5、什么时候定义构造函数呢?

    当分析事物时,该事物具备一些特性和行为,那么就将这些内容定义在构造函数内。

6、构造代码块

   作用:给对象进行初始化。

   运行时间:对象一旦建立,就运行,而且优先于构造函数运行。  

   与构造函数的区别:

  构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化。

  构造代码块中

定义的是不同对象共性初始化的内容。

构造代码块定义格式

class Person

{

private String name;

private int  age;

/*构造代码块举例如下*/

{

    System.out.println(person  code  run)

}

  Person() //构造函数

{

 

}

.......

}

7、构造函数是可以私有化的,因为构造函数也是成员函数中的一员。但是,

给构造函数私有化以后,会产生一个现象,就是外界对象是不可能通过这个构造函数建立成功的。

举一反三:如果把一个类中的所有的构造函数都私有化,就说明这个类是不可能被创建对象的。

五、This关键字

class Person

{

private String name;

private int age;

Person(String name)//局部变量定义为name是为了方便阅读

{name=name;}

}

这时,运行程序会发现,创建对象,name=null,没有被赋值为实参变量

因为构造函数会先去找本函数中的局部变量。该怎么标识成员变量name呢?用  关键字this,写为   this.name=name;

 

   

1、this的基本应用:

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

     2) 用于构造函数之间进行互相调用

    

     注解:   this语句只能定义在构造函数的第一行。因为初始化要先执行。

        this的两种用法:1、用于区分同名变量的情况,说的成员和局部同名的时候;2、用于构造函数间调用。

                  this语句不能用在一般函数中,只能用在构造函数间。

六、static关键字


   static是一个修饰符,用于修饰成员(成员变量和成员函数)。当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用。格式:类名.静态成员。

当内存中存在多个对象,具有相同的数据时,

例如

class Person

{

String name;

 static String country=CN;

}

每一个进入公司的人,姓名可以不同,但国籍都是相同的,这样建立每一个对象,在内存中都存储国籍,相同的数据,会出现很多重复。

我们可以把country单独取出来,放在一个地方,谁用,谁就取出来。这时,就用到static修饰的共享变量。

   当变量被修饰为static变量时,就不在堆内存中存储了,而是被提取到方法区,这样每个对象都可以访问。

1、 static特点:

     1)随着类的加载而加载。

             也就是说:静态会随着类的消失而消失,所以它的生命周期最长。

        2)优先于对象存在。明确一点:静态是先存在。对象是后存在。

        3)被所有对象所共享。

        4)可以直接被类名所调用。

       由于静态成员可以直接被类名调用,因此静态成员变量又称为类变量。而非静态成员变量又被称为实例变量。

  实例变量和类变量的区别:

1)存放位置 

  类变量随着类的加载而存在于方法区中。实例变量随着对象的创建而存在堆内存中。

2) 生命周期

  类变量最长,随着类的消失而消失。而实例变量生命周期随着对象消失而消失。

 

2、静态使用注意事项

静态方法只能访问静态成员变量和方法。

 非静态方法既可以访问静态成员变量和方法,也可以访问非静态

静态方法中不可以定义this、 super关键字,因为静态优先于对象存在

3、静态的优缺点:

 优点是节约内存,对共享数据,单独存储,节省了堆内存的空间。

 缺点:

  a.生命周期过长

  b.访问出现局限性  只能访问静态成员。

4、什么时候使用静态?

  从两方面下手: 因为静态修饰的内容有成员变量和函数。

           1) 什么时候定义静态变量(类变量)呢?

                 当对象中出现共享数据时,该数据被静态所修饰。

                对象中的特有数据要定义成非静态存在于堆内存中。

          2)什么时候定义静态函数呢?

               当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。

 5、静态代码块


    格式:

static

{

  静态代码块中的执行语句;

}

  静态代码块的特点:

      1)随着类的加载而执行,只执行一次,并且优先于主函数执行。

    2)用于给类进行初始化。

对象在内存中的初始化过程

 也就是new操作符在内存中所做的操作。

   1)把类名.class文件加载到内存中。

        2)执行该类中的static代码块,如果有得话,给该类进行初始化。

        3)在堆内存中开辟空间,分配内存地址。给对象

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

        5)对属性进行显示初始化。

        6)对对象进行构造代码块初始化。

        7)对对象进行对应构造函数初始化。

        8)将内存地址赋值给栈内存中的对象名变量。

6、静态的应用——制作工具类文档说明书

每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装,以便复用。

比如

定义个工具类

  

  

  

   


     

dos命令行中输入命令:javadoc -d  e:\myclasstool -author-version ArrayTool.java

Java中的javadoc工具就会帮我们完成说明文档也称API的制作。

到e:\myclasstool\下找到index.html文件打开

7、静态的使用——主函数

主函数是一个特殊的函数,作为程序的入口,可以被jvm调用。

主函数的定义

public 代表着该函数的访问权限是最大的,是被虚拟机访问的

static  代表着主函数随着类的加载就已经存在了

把类名告诉虚拟机,虚拟机就已经以  类名.main 来访问主函数了

void  主函数没有具体的返回值。


main   不是关键字,但是是一个特殊的单词,可以被jvm识别


主函数的使用:

class MainDemo

{

public static void  main(String []args)

{

String [] arr={haha,heihei,hehe,xixi};

MainTest.main(arr);

}

}

class MainTest

{

public static void main(string[]args)

{

for(int i=0;i<args.length;i++)

       {

         System.out.println(args[i]);

}

} 

}


七、单例设计模式

设计模式就是解决某一类问题行之有效的方法,集合成模式,帮助开发。

几个模式综合运用,就形成复杂的框架。java共有23中通用模式。

其中有一种叫做单例设计模式:用于解决一个类在内存中只有一个对象,确保对象唯一。


思想:

1)为了避免其他程序的过多建立该类对象,先禁止其他程序建立该类对象

2)还为了让其他程序可以访问到该类对象,只好在本类中自定义一个对象。

3)为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

需要三步:

 1)将构造函数私有化

 2)在类中创建本类对象

 3)提供一个方法可以获取到本类对象

举例

class Single

{

private single(){}

private static  Single s=new Single(); //成员变量为类对象。

public static  single getInstance()

{

  return s;

}

}

单例设计模式的两种方法:

方法一:饿汉式。

特点是先初始化对象。是比较安全的方式。

 

 

方法二、懒汉式。

特点是当调用创建实例方法时,才初始化对象,这称之为延时加载。当在多线程中,容易出现并发问题。

当在多线程的系统中,两个线程访问该类,并在方法中被冻结了,就容易发生问题,因此,采用锁机制来解决这个问题

因此,最终的懒汉式代码为:

 

   

  





------ Java培训、Android培训、iOS培训、.Net培训 、期待与您交流! -------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值