黑马程序员-Java基础学习第五天总结

来源:互联网 发布:薛之谦 离婚 知乎 编辑:程序博客网 时间:2024/04/30 13:50
------- android培训、java培训、期待与您交流! ----------

3-1 面向对象概括

3-1-1 理解面向对象

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

面向过程
强调的是功能行为。
代表语言:C语言。

例子:把大象装进冰箱
1、打开冰箱。
2、存储大象。
3、关上冰箱。
"打开"、"存储"、"关上"都是功能行为,在代码中的直观体现就是函数或者方法,这就是一种面向过程的以功能行为为主体的思想体现。

面向对象
将功能封装进对象,强调具备了功能的对象。
代表语言:Java、C++、C#。

注意:
面向对象是基于面向过程的。

例子:把大象装进冰箱
1、冰箱打开。
2、冰箱存储。
3、冰箱关闭。
可以看到,所有的操作都是以"冰箱"为主体,而不是功能行为。
也就是说冰箱自己已经具备"打开"、"存储"、"关上"的行为功能,我们只需要让冰箱执行它具备的功能就可以了。
这就是一种面向对象的以执行功能的对象为主体的思想体现。

3-1-2 面向对象的特点

是一种符合人们思考习惯的思想,可以将复杂的事情简单化,将程序员从执行者转换成了指挥者。

完成需求时:
1、先要去找具有所需的功能的对象来用。
2、如果该对象不存在,那么创建一个具有所需功能的对象。
这样可以简化开发并提高复用。

3-1-3 面向对象开发,设计,特征
开发的过程:
其实就是不断的创建对象,使用对象,指挥对象做事情。

设计的过程:
其实就是在管理和维护对象之间的关系。

面向对象的特征:
封装(encapsulation)
继承(inheritance)
多态(polymorphism)

3-2 类与对象的关系 
使用计算机语言就是不断地在描述现实生活中的事物。
java中描述事物通过类的形式体现,类是具体事物的抽象,概忥上的定义。
对象即是该类事物实实在在存在的个体。

3.2.1 类与对象(图例)

类与对象的关系如图:


可以理解为:类就是图纸,汽车就是堆内存中的对象。

对于同一类事物可以抽取它们的共性的内容,定义在类中。如:生活中的汽车,每一台车都有轮胎数和颜色。
那么在通过java描述汽车这类事物时,就可以将这两个共性属性作为类中的属性进行定义。
通过该类建立的每一个汽车实体都具有该属性,并可以有对象特有的属性值。

3.2.2 类的定义

生活中描述事物无非就是描述事物的属性和行为。
如:人有身高,体重等属性,有说话,打球等行为。

Java中用类class来描述事物也是如此。
属性:对应类中的成员变量。
行为:对应类中的成员函数。
定义类其实在定义类中的成员(成员变量和成员函数)。

3.2.3 成员变量和局部变量的区别?

成员变量:
①成员变量定义在类中,在整个类中都可以被访问。
②成员变量随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。
③成员变量有默认初始化值。

局部变量:
①局部变量只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。
②局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放。
③局部变量没有默认初始化值。

3.2.4 匿名对象

匿名对象是对象的简化形式。
匿名对象两种使用情况:①当对对象方法仅进行一次调用时;②匿名对象可以作为实际参数进行传递。

class Car{     String color = "red";     int num = 4;     public static void run()     {          System. out.println("function run is running!" );     }}class CarDemo{       public static void main(String[] args){             //对对象方法仅进行一次调用时,就可以使用匿名对象             new Car().run();             //匿名对象可以作为实际参数进行传递            show(new Car());      }       public static void show(Car c){            c. num = 3;            c. color = "black" ;            System. out.println("function show is running!" );            System. out.println(c.num + "..." + c. color);      }}

3-3 封装(Encapsulation)

封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
1、 概念
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

2、好处:
①将变化隔离。
②便于使用。
③提高重用性。
④提高安全性。


3、 原则
a) 将不需要对外提供的内容都隐藏起来。
b) 把属性都隐藏,提供公共方法对其访问。


4、 封装的表现形式之一——private(私有)
private关键字:权限修饰符;用于修饰类中的成员(成员变量,成员函数);私有只在本类中有效。
常用之一:
将成员变量私有化,对外提供对应的set,get方法对其进行访问。提高对数据访问的安全性。
如:我有一个人对象,而年龄这一属性我不想被对象访问,我就可以将其设为private。

注意:
1、私有仅仅是封装的一种体现而已。
2、private关键字:是一个权限修饰符,用于修饰成员(成员变量和成员函数),被私有化的成员只在本类中有效。
常用场景之一:将成员变量私有化,对外提供对应的set、get方法对其进行访问,提高对数据访问的安全性。

3-4 构造函数

特点:
①函数名与类名相同。
②不用定义返回值类型。
③没有具体的返回值。
附:在构造函数前面加上返回值就只是一般函数了。

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

class Person{       private String name ;       private int age ;       //定义一个Person类的构造函数       //构造函数,而且是空参数的      Person(){            System. out.println("person run" );      }       public void speak(){            System. out.println(name + ":" + age);      }}class ConsDemo{       public static void main(String[] args){             //构造函数:构建创造对象时调用的函数             //作用:可以给对象进行初始化            Person p = new Person();            p.speak();      }}

注意:
1、一般函数和构造函数什么区别呢?
构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化。
一般函数:对象创建后,需要函数功能时才调用。

构造函数:对象创建时,会调用并且只调用一次。
一般函数:对象创建后,可以被调用多次。

2、创建对象都必须要通过构造函数初始化。
一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数。
如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。

3、多个构造函数是以重载的形式存在的。

3-5 this关键字

this代表其所在函数所属对象的引用。换言之,this代本类对象的引用。
当成员变量和局部变量重名,可以用关键字this来区分,this就是所在函数所属对象的引用。
简单说,哪个对象调用了this所在的函数,this就代表哪个对象。一般方法调用默认加this。

什么时候使用this关键字呢?
当在函数内需要用到调用该函数的对象时,就用this。

class Person  {      private String name;      private int age;      Person(int age)//局部变量时age,成员变量也是age      {          this.age = age;//this能够很好区分      }      Person(String name)      {          this.name = name;//这里用this表示调用构造方法的对象      }      Person(String name,int age)      {          this.name = name;          this.age = age;      }        public void speak()      {          System.out.println("name="+name+"...age="+age);          show();      }      public void show()      {          System.out.println(this.name);      }  }  

以上程序综合了构造函数和this的用法。看上去,是用于区分局部变量与成员变量同名情况。
this代表它所在函数所属对象的引用。
简单说:哪个对象在调用this所在的函数,this就代表哪个对象。

this的应用:
当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
但凡本类功能内部使用到了本类对象,都用this表示。

this语句:
用于构造函数之间进行互相调用。如:this(name);
thi语句只能定义在构造函数的第一行。因为初始化要先执行。

对this的概括总结:
this的两种用法:1、用于区分同名变量的情况,说的成员和局部同名的时候;2、用于构造函数间调用。
注:一般函数不能直接调用构造函数,因为this语句不能用在一般函数中,只能用在构造函数间。

3-6 static关键字

static关键字:
用于修饰成员(成员变量和成员函数)。

被修饰后的成员具备以下特点:
①随着类的加载而加载。
②优先于对象存在。
③被所有对象所共享。
④可以直接被类名调用。

由于静态成员可以直接被类名调用,因此静态成员变量又称为类变量。而非静态成员变量又被称为实例变量。
实例变量和类变量的区别:
1、存放位置。
类变量随着类的加载而存在于方法区中。
实例变量随着对象的建立而存在于堆内存中。
2、生命周期。
类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。
静态有利有弊:
利处:对对象共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。可以直接被类名调用。
弊端:生命周期过长。
访问出现局限性。(静态虽好,只能访问静态)。
静态需要清楚的几个小问题:
什么时候使用静态?
从两方面下手: 因为静态修饰的内容有成员变量和函数。

静态使用注意事项:
1、静态方法只能访问静态成员。
非静态方法既可以访问静态也可以访问非静态。
2、静态方法中不可以定义this,super关键字。
因为静态优先于对象存在。所以静态方法中不可以出现this。
3、主函数是静态的。
静态代码块:
格式:
static
{
静态代码块中的语句。
}
特点:随着类的加载而执行,执行一次。并优先于主函数。用于给类进行初始化。
对象的初始化过程:
定义一个新对象都做了哪些事情?
1、把类名.class文件加载到内存中。
2、执行该类中的static代码块,如果有得话,给该类进行初始化。
3、在堆内存中开辟空间,分配内存地址。给对象
4、在堆内存中建立对象的特有属性。并进行默认初始化。
5、对属性进行显示初始化。
6、对对象进行构造代码块初始化。
7、对对象进行对应构造函数初始化。
8、将内存地址赋给栈内存中的对象名变量。
静态的应用——文档说明书。
每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装。以便复用。

成员变量和静态变量的区别?
1、两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象被回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2、调用方式不同
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3、别名不同
成员变量也称为实例变量。
静态变量也称为类变量。
4、数据存储位置不同
成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。

使用注意:
①静态方法只能访问静态成员,如果访问非静态成员,就会报错!
原因:静态方法和变量存在的时候,对象还不存在,非静态变量也不存在,肯定无法访问。

注意:
非静态方法既可以访问静态成员,又可以访问非静态成员。

②静态方法中不可以写this,super关键字。
原因:静态方法存在的时候,对象还不存在,this代表的就是调用方法的那个对象,既然不存在,肯定不可以写在静态方法中。

③主函数是静态的
主函数特殊之处:
1、格式是固定的。
2、被jvm所识别和调用。

主函数各成分解析:
public:权限必须是最大的,被jvm调用。
static:不需要对象调用,直接用主函数所属类名调用即可。 命令行窗口中输入:java StaticDemo,实际上就是在执行StaticDemo.main();。
void:主函数不需要具体的返回值。
main:函数名,不是关键字,只是一个jvm识别的固定的名字。
String[] args:这是主函数的参数列表,是一个数组类型的参数,而且元素都是字符串类型。

静态什么时候用?
①静态变量

当分析对象中所具备的成员变量的值都是相同时,这时这个成员就可以被静态修饰。
只要数据在对象中都是不同的,就是对象的特有数据,必须存储在对象中,是非静态的。
如果是相同的数据,对象不需要做修改,只需要使用即可,不需要存储在对象中,定义成静态的。

②静态函数

函数是否用静态修饰,就参考一点,就是该函数功能是否需要访问到对象中的特有数据。
简单点说,从源代码看,该功能是否需要访问非静态的成员变量,如果需要,该功能就是非静态的。
如果不需要,就可以将该功能定义成静态的。当然,也可以定义成非静态,但是非静态需要被对象调用。
如果没有访问特有数据的方法,该对象的创建是没有意义。

下面我们以一个数组工具类为例,作一个文档说明书。

/** 这是一个可以对数组进行相关操作的工具类,该类提供了取数组的最值、排序等功能。 @author Godream @version V1.0  */  //类名权限要最大才能创建说明书文档  public class ArrayTool   {      /**     空参数构造函数     */      private ArrayTool() //私有化构造函数是为了让其不能创建对象。      {            }        /**     这个功能用于得到int类型数组中的最大值     @param arr 接收一个int类型的数组     @return 返回接收的该数组的最大值     */      public static int getMax(int[] arr)      {          int max=0;          for (int x=1;x<arr.length ;x++ )          {              if(arr[x]>arr[max])                  max=x;          }          return arr[max];      }            /**     这个功能用于得到int类型数组中的最小值     @param arr 接收一个int类型的数组     @return 返回该数组的最小值     */      public static int getMin(int[] arr)      {          int min=0;          for (int x=1;x<arr.length ;x++ )          {              if(arr[x]<arr[min])                  min=x;          }          return arr[min];      }        /**     对int类型数组进行选择升序排列     @param arr 接收一个int类型的数组     */      public static void selectSort(int[] arr)      {          for (int x=0;x<arr.length-1 ; x++)          {              for (int y=x+1; y<arr.length; y++)              {                  if(arr[x]>arr[y])                      swap(arr,x,y);              }          }      }        /**     对int类型数组进行冒泡升序排列     @param arr 接收一个int 类型数组     */      public static void bubbleSort(int[] arr)      {             for (int x=0;x<arr.length-1;x++ )          {              for (int y=0;y<arr.length-x-1;y++ )              {                     if(arr[y]>arr[y+1])                      swap(arr,y,y+1);              }          }      }        /**     对数组中的两个元素进行位置交换     @param arr 接收一个int类型的数组     @param a 要置换的元素角标     @param b 要置换的元素角标     */      private static void swap(int[] arr,int a,int b)      {          arr[a]=arr[b]+(arr[b]=arr[a])*0;      }        /**     遍历数组:打印数组中所有元素,形式为:[elemet1,elemet2,...]     @param arr 接收一个int类型的数组     */      public static void printArray(int[] arr)      {          System.out.print("[");          for (int x=0; x<arr.length-1; x++)          {              System.out.print(arr[x]+",");          }          System.out.println(arr[arr.length-1]+"]");      }  }  

在dos命令行中输入命令:javadoc -d Myhelp -author-version ArrayTool.java
Java中的javadoc工具就会帮我们完成说明文档也称API的制作。


结果:


注意:
1、如果想把一个类进行文档化,该类必须是public的。
2、私有的方法在文档中不会体现,例如ArrayTool类中的swap方法。

3-7 单例设计模式

设计模式:对问题行之有效的解决方式,其实它是一种思想。

单例设计模式解决的问题:就是可以保证一个类在内存中的对象唯一性。

比如多个程序使用同一个配置信息对象时,就需要保证该对象的唯一性。
如何保证对象唯一性呢?
①不允许其他程序用new创建该类对象。
②在该类创建一个本类实例。
③对外提供一个方法让其他程序可以获取该对象。

步骤:
①私有化该类构造函数。
②通过new在本类中创建一个本类对象。
③定义一个公有的方法,将创建的对象返回。

饿汉式:

class Single{       //类已加载,对象就已经存在了       private static Single s = new Single();       private Single(){}       public static Single getInstance(){             return s ;      }}class SingleDemo{       public static void main(String[] args){            Single s1 = Single.getInstance();            Single s2 = Single. getInstance();            System. out.println(s1 == s2);      }}

注意:
之所以不用Single.s;的方式获取Single对象,而采用getInstance获取是因为在getInstance方法中我们可以做一些判断来决定是否返回Single的对象,也就是实现了对单例对象的可控。
所以,给Single的构造方法加上了private限制,禁止使用者直接采用Single.s;的方式获取。

<strong>示例(懒汉式):</strong>Single.javaclass Single{       //类加载进来,没有对象,只有调用了getInstance方法时,才会创建对象       //延迟加载形式       private static Single s = null;       private Single(){}       public static Single getInstance(){             if(s == null)                   s = new Single();             return s ;      }}class SingleDemo{       public static void main(String[] args){            Single s1 = Single. getInstance();            Single s2 = Single. getInstance();            System. out .println(s1 == s2);      }}


0 0
原创粉丝点击