黑马程序员——面向对象

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

一,面向对象的概念

1,理解面向对象

· 面向对象是相对面向过程而言

· 面向对象和面向过程都是一种思想

· 面向过程

强调的是功能行为

· 面向对象

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

· 面向对象是基于面向过程的

例:功能是将东西存储进冰箱。面向过程的思想就是先打开冰箱,存储事物,关闭冰箱;如果是面向对象的思想,将打开、储存、关闭都封装在冰箱里。就成为了,冰箱.打开 冰箱.存储 冰箱.关闭

2,面向对象的特点

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

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

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

· 完成需求时:

a. 先要去找具有所需功能的功能对象来使用

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

c. 这样简化开发提高了代码的复用

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

· 开发的过程:其实就是不断的创建对象,使用对象,指挥对象做事情

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

· 面向对象的特征:

a. 封装(encapsulation) 

b. 继承(inheritance)

c. 多态(polymorph)

· 面试题:面向对象是什么?

答:面向对象是一种思想,可以让复杂的事情简单化,将执行者变成指挥者。举例一般可以随着实际场景出发。比如公司招人就是一种面向对象的思想,调用的就是招聘者身上的工作的功能

二,类与对象的关系

· 使用计算机语言就是不断的在描述现实生活中的事物

· java中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义

· 对象即是该类事物实实在在存在的个体

1,类与对象

· 类与对象的关系如图示例:

黑马程序员——面向对象_第1张图片

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

2,类的定义

· 生活中描述事物无非就是描述事物的属性和行为

 如:汽车会有排量,颜色等属性

· java中用类描述事物也是如此

属性:对应类中的成员变量

行为:对应类中的成员函数

如:描述汽车(排量,颜色)。

· 定义类其实在定义类中的成员(成员变量和成员函数)

3,成员变量和局部变量的区别?

· 成员变量,作用于整个类中;在堆内存中,因为对象的存在而存在;有默认初始化值

· 局部变量,局部变量作用于函数或者语句中,存在于栈内存中

4,创建对象,使用对象

class Car { //对Car这类事物进行描述
   String color = "red";
   int num = 4;
   void show() {
      Ststem.out.println(“color=”+color+”..num=”+num);
   }
}
class CarDemo
{
   public static void main(String main[]) {
      Car c = new Car();//建立对象
      c.color = “black”;//对对象的属性进行修改
      c.show();//使用对象功能
   }
}

5,对象内存结构

Car c1 = new Car(); c1.color="blue";

Car c2 = new Car();

c1、c2的引用存在于栈内存中,当执行到new Car()时,才在堆内存中建立实体,并根本这类事物,一开始c1的初始化color为"blue"。执行到c1.color="blue"时,在堆内存把red换为blue

6,匿名对象

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

· 匿名对象两种使用情况

a. 当对象方法仅进行一次调用时。例:new Car().show();

b. 匿名对象可以作为实际参数直接传递。例:有一个run(Car c)的方法,可以直接写成run(new Car());

三,private(私有)关键字

· private是一个权限修饰符,用于修饰成员(成员变量和成员函数)。被私有化的成员只在本类中有效

· 常用之一:将成员变量私有化,对外提供get和set方法进行访问,提高数据访问的安全性

构造函数:

a. 函数名和类名相同

b. 不用定义返回值类型

c. 不可以写return语句

· 对象一建立就会调用与之相对应的构造函数,所以构造函数的作用:可以用于给对象进行初始化动作。

· 当一个类没有定义构造函数时,那么系统会默认给该类加入一个空参数构造函数

· 当在类中自定义了构造函数后,默认的构造函数就没有了

· 构造函数和一般函数在写法上不同,在运行上也不同。构造函数是对象一建立就运行,给对象进行初始化。而一般方法是对象调用才执行,给对象添加对象需要具备的功能。一个对象的建立,其构造函数只运行一次,而方法可以被多次调用。

· 什么时候定义构造函数?当分析事物时,该事物存在具备一些特性或者功能,那么将这些内容定义在构造函数中,

总结:根据构造函数的参数不同,所对应的构造函数也不同。当自己写了构造函数后,系统就不会添加默认构造函数。当创建对象时,会根据参数选择对应的构造函数并进行初始化动作。如果一个函数不想被创建对象,自己写一个空参数的构造函数并私有化。

构造代码块:

作用:给对象进行初始化。对象一建立就运行,并且优先于构造函数。

构造函数和构造代码块的区别?

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

例:有一个功能要在所有构造函数内容运行之前都要运行,就可以写在构造代码块中运行。这样所有的构造函数在运行前都会先运行构造代码块中的内容。

四,封装

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

· 好处:

a. 将变化隔离

b. 便于使用

c. 提高重用性

d. 提高安全性

· 封装原则:

a. 将不需要对外提供的内容隐藏起来

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

· 例:电脑的主机相对于我们来说就是被封装的,电脑里面的硬件都是封装在电脑的机箱里面的。这样,电脑里面不管是换了什么硬件,对我们来说是没关系的,这就是将变化隔离的特性。把内容封装之后,提供固定的对外的接口让我们使用,这就提高了使用性。不能对内部进行操作,也是提高了安全性。

· 代码实例:需求:描述一个人的类。人有年龄。但是年龄需要一个合理的值,所以可以把年龄封装在人的类中。提供对外访问的方法对年龄进行操作。在设置方法中在对年龄进行逻辑判断

class Person {
   private int age;
   //对外提供get,set方法
   public void setAge(String age) {
      if(age>0 && age<130)
         this.age= age;
      else
         System.out.println(“年龄非法”);
   }
   public int getAge() {
      return age;
   }
}

五,this关键字

this:代表本类对象,代表它所在函数所属对象的引用。简单地说,哪个对象在调用this所在的函数,this就代表哪个对象。

· 什么时候使用this关键字呢?

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

· this关键字的应用:例:一个Person对象中有age属性,并在创建的时候就需要赋值。现在需要一个方法判断两个对象中的age是否相同。

main函数中,这样写:

Person p1 = new Person(20);

Person p2 = new Person(25);

p1.compare(p2);

Personcompare方法:

public boolean compare (Person p) {

   return this.age = age;

}

在这个方法中,因为是p1调用的这个方法,所有this代表的是p1

· this关键字在构造函数间调用:

this() 用于构造函数之间的传递,并且只能定义在构造函数的第一行,因为初始化要先执行。

例:在Person中有2个构造函数

Person(String name) {

    this.name = name;

}

Person(String name,age) {

   this(name);

   this.age = age;

}

这段代码的this.name就是在构造函数中传递这个name参数。

当我们对外只提供很少的构造函数时,自己内部可以使用大量的构造函数。这时就可以使用这种this的使用情况!

2:在Person中有2个构造函数,

Person() {

   this(“a”);

};

Person(String name) {

   this();

}

这种情况是不允许存在的。无限死循环....


六,static关键字

static的用法:

· 是一个修饰符,用于修饰成员(成员变量和成员函数)

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

a. 随着类的加载而加载。也就是说,静态会随着类的消失而消失

b. 优先于对象存在。明确一点,静态是先存在,对象是后存在的

c. 被所有对象共享

d. 可以直接被类名调用:类名.静态成员

e. static修饰的类,存放在方法区(共享区,数据区)

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

· 在一个类中,被static修饰的成员称为类变量。未被static修饰的变量称为实例变量

1. 存放位置:类变量随着类的加载而存在于方法区中;实例变量随着对象的建立而存在于堆内存中

2. 生命周期:类变量生命周期最长,随着类的消失而消失;实例变量生命周期是随着对象的消失而消失

使用注意:

· 静态方法只能访问静态成员,非静态方法既可以访问静态也可以访问非静态

· 静态方法中不可以写this、super关键字。因为静态优先于对象存在,所以静态方法中不可以出现this

· 主函数是静态的

主函数:

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

· 主函数的定义:

public:函数访问权限最大

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

void:主函数没有具体返回值

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

(String args[]):函数的参数,参数类型是一个数组。该数组中元素是字符串。args是可以修改的,变量名只要合法就行。原先是argument

· 主函数的格式是固定的:jvm识别

静态的利弊:

· 好处:

a. 对对象的共享进行单独空间的存储,节省空间。没有必要每一个对象都要存储一份

b. 可以直接被类名调用

· 弊端:

a. 生命周期过长

b.访问出现局限性,因为静态只能访问静态

静态的应用:

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

· 如果我们有一个工具类,可以把工具类中所有的方法都定义成static的,直接通过类名调用

· 通过javadoc -d myhelp -author -version 类名.java 编写说明书

静态代码块:

· 格式:

static {

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

· 特点:随着类的加载而执行,只执行一次

例:在main函数中一句Person p = new Person("张三",20); 这句话都做了哪些事情?

1,因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中

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

3,在堆内存中开辟空间,分配内存地址

4,在堆内存中建立对象特有的属性,并进行默认初始化(姓名,年龄)

5,对属性进行显示初始化

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

7,对对象进行对应的构造函数代码块初始化

8,将内存地址赋给栈内存中的p变量

七,扩展知识——设计模式
· 设计模式:解决某一类问题最行之有效的方法
· Java中有23中设计模式:介绍其中的单例设计模式

· 单例设计模式:解决一个类在内存中只存在一个对象

· 想要保证对象的唯一性:

a. 为了避免其他程序过多建立该类对象,先禁止其他类创建该对象

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

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

· 用代码实现:

a. 将构造函数私有化

b. 在类中创建一个本类对象

c. 提供一个方法可以获取到该对象

· 代码:

class Single {//饿汉式,类一进内存,就已经创建好对象
   private static Single s = new Single();
   private static () {}
   public static Single getInstance() {
      return s;
   }
}
class Single {//懒汉式,对象是方法被调用时才初始化。这也叫类的延时加载
   private static Single s = null;
   private Single() {}
   public static Single getInstance() {
      if(s==null) {
         synchronized(Single.class) {
            if(s==null) {
               s = new Single();
            }
         }
      }
      return s;
   }
}








你可能感兴趣的:(java,黑马程序员)