黑马程序员—【Java基础篇】之面向对象

------- android培训java培训、期待与您交流! ---------

    这篇分享和总结Java之面对对象。

    主要学习型内容有:1.面向对象概念;2. 类与对象的关系;3 .封装;4. 构造函数;5. this关键字;6 static关键字;7 单例设计模式。一共七个部分,接下来一一总结。大笑微笑

一、面向对象概念

    第一句话:万物皆对象。传说这是老妖精才能说的话,我们现在说,是很装格调哈,来起吧,伙伴们。

    “java是一种面向对象的编程语言,也就是说对象是这种语言的基础,没有对象了,就没有了java。”我个人觉得这句话很经典,所以就接过来用一下。

    举个例子:如把鸡蛋装进冰箱。

    c语言强调的是功能行为:打开冰箱——>把鸡蛋装进冰箱——>关闭冰箱。

   Java面向对象的思想就是强调冰箱具有功能的对象:冰箱打开,冰箱存储,冰箱关闭。感觉上就是过程是你自己亲自在做,而面向对象却是你指挥着对冰箱去做。

1、理解

    一种符合人们思考习惯的思想;可以将复杂的事情简单化;先要去找具有所需的功能的对象来用;将程序员从执行者转换成了指挥者。

    面向对象的三个特征:封装性,继承性,多态性。

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

    Java设计的过程,其实就是在管理和维护对象之间的关系。多态性。  

       人是一个对象,人有吃饭,睡觉以及学习等等的行为(可称为功能),那么就是将吃饭、睡觉以及学习等功能封装进人这个的事物中,让人去执行这些功能,是人在调用这些方法,从而简化了过程。  

二、类与对象的关系

1、类与对象的关系

    先看一个示例图:


    

    图纸就是类;根据图纸造出来的一辆辆汽车就是对象。

       类(class):可以理解为是构造对象的一个蓝图或者模板,是抽象的概念;反过来说,对象是以类为模型创造的具体实例,是对类的一种具体化、形象化。
        类:对生活中事物的描述
        对象:对类的具体实现,是实实在在存在的实体。
       例如:汽车的设计
        类:指的是汽车的设计图纸
        对象:指实际生产出来的汽车。

/** 
需求:定义一个汽车类,要求设计出汽车的型号(即名字),颜色,轮胎个数,行驶速度,并且让汽车行驶起来(即打印出每个汽车的颜色、轮胎数、速度)并比较两辆汽车之间那个性能更好:即速度快慢 
思路: 
    1.创建一个构造函数,即一个汽车类,对其的颜色,轮胎数
    2.创建一个汽车对象,实现其功能 
    3.构造一个方法,比较两辆车之间的速度
*/
class Car{   
    String name;  
    String color;  
    int nums;  
    double speed;  
    Car(String name,String color,int nums,double speed)  
    {  
        this.name = name;  
        this.color = color;  
        nums = 4;  
        this.speed = speed;  
        System.out.println(name + "是一辆" + color + ",轮胎数是:" + nums + ",可以行驶的速度是:" + speed);  
    }  
      
    public void compare(Car c)  
    {  
        if(this.speed > c.speed)  
        {  
            System.out.println(this.name + "行驶得更快。");  
            return;  
        }  
        System.out.println(c.name + "行驶得更快。");  
        return;  
    }  
}  
  
class CarDemo  
{  
    public static void main(String[] args)   
    {  
        Car x = new Car("Jeep","红色",4,500);  
        Car y = new Car("法拉利","橙色",4,600);  
        x.compare(y);  
    }  
}

   上面汽车的例子中,a、bc是局部变量,定义在了方法中,存在于栈内存中;而name、color、nums和speed都是成员变量,存在于堆内存中,随着类的加载而加载。

2、成员变量与局部变量

   不同处:

(1)作用范围
    a. 成员变量:作用于整个类中;
    b. 局部变量:作用于函数中,或者作用于语句块中;
(2)内存中的位置
    a. 成员变量:在堆内存中,因为对象的存在才在内存中存在;
    b. 局部变量:在栈内存中,随着函数的结束而消亡;
(3)初始化方式
    a. 成员变量:随着类的初始化而初始化,在堆内存中被加载,有默认值,可直接参与运算;
    b. 局部变量:随着方法的加载而加载进栈内存中,无初始化值,必须被初始化才能参与运算;

3、匿名对象

    对象的简化形式:匿名对象。例: new Car();

    匿名对象两种使用情况
   (1)当对对象方法仅进行一次调用的时。
   (2)匿名对象可以作为实际参数进行传递。
注:如果对一个对象进行多个成员调用,必须给这个对象起个名字。

     匿名对象与实名对象的区别:

    但是这个对象实体在方法结束后,垃圾回收机制会将其作为垃圾回收。而非匿名对象则不同,当不使用了,会在某一时刻被回收,或是随着主函数的结束而被回收。

三、封装(Encapsulation)

1、 概念

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

2、 好处

    (1)将变化隔离。
    (2)便于使用。
    (3)提高重用性。
    (4)调高安全性。

3、 原则

    (1) 将不需要对外提供的内容都隐藏起来。
    (2) 把属性都隐藏,提供公共方法对其访问。

4、说明

    (1)私有仅仅是封装的一种表现形式,如包也是一种封装形式

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

5、private(私有)关键字

  (1)用于修饰成员(成员变量和成员函数)
  (2)被私有化的成员只在本类中有效。
  (3)常用之一:
    将成员变量私有化,对外提供对应的set ,get方法对其进行访问。提高对数据访问的安全性; 是一个权限修饰符。

    例如:

class Person//描述人对象的类  
{  
    private int age;//人对象的年龄属性,private(关键字)  
    public void setAge(int a)//提供访问方法,并判断是否有效  
    {  
        if(a>0 && a<130)  
        {  <pre name="code" class="java"><span style="white-space:pre">		</span>age = a;<pre name="code" class="java"><span style="white-space:pre">		</span>speak();
<pre name="code" class="java"><span style="white-space:pre">	</span>}  
        else{  
            System.out.println("非法数值");  
<span style="white-space:pre">	</span>}  
     }
    public int getAge()//提供公共获取方法,同时返回int值,必须return语句。<pre name="code" class="java"> {  
        return age;  
    }  
    private void speak()//私有说功能  
    {  
        System.out.println("age="+age);  
    }  
}  
  
class PersonDemo    
{  
    public static void  main(String[] args)  
    {  
        Person p = new Person();//创建人对象 ,主函数调用。 
        p.setAge(-50);//利用封装提供public访问方法进行修改年龄属性  
        p.speak();  
    }  
}  
 
 
 
 

四、构造函数

1、 特点

    (1)  函数名与类名相同。

    (2)  不用定义返回值类型。

    (3)  不可以写return语句。

2、 作用

    (1) 给对象进行初始化。

3、注意事项

    当一个类中没有定义构造函数时,那么系统就会默认给该类加入一个空参数的构造函数。当在类中自定义了构造函数后,默认的构造函数就没有了。

4、构造函数和一般函数区别

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

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

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

6、构造代码块

(1) 作用:给对象进行初始化;对象一建立就运行,而且优先于构造函数运行。 (2) 构造代码块构造函数的区别     a、 构造代码块是给所有的对象进行初始化,即每个对象都会有的特性。     b、而构造函数是给对应的对象初始化;     c 、构造代码块中定义的是不同对象共性的初始化内容。

<span style="font-family:SimSun;"><span style="font-size:12px;">class Person
{  private String name;</span></span><pre name="code" class="java"><span style="font-family:SimSun;font-size:12px;">   private  int  age;
{
    System.out.println("Person")//构造代码块
    cry();
}</span>
 

五、this知识点

    毕老师上课的一个例子:

class Person  //声明Person类
{  
    private String name;  
    private int age;  
    Person(int age)//局部变量时age,成员变量也是age  
    {  
        this.age = age;//对象传进来的age给了全局变量age。 
    }  
    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);  
    }  
}  

1、特点

    this代表其所在函数所属对象的引用。换言之:this代本类对象的引用。

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

    当在函数内需要用到调用该函数的对象时,就用this。

六、static(静态)关键字

1、 存在的意义

    内存有一片地方是静态方法区,专门存放静态常量和方法的区域,当一个变量或者方法是所有对象都共有的,那么为了提高效率和内存使用率,就产生了static。

 2、 特点

    (1)随着类的加载而加载,在类中生命周期最长;
    (2)优先于对象而存在;
    (3)可以被所有对象共享;
    (4)可以直接被类名调用。

3、用途

    (1)修饰成员:成员变量和成员方法。

    (2)当成员被static修饰后,就多了一种调用方式,即可以被对象和类名调用。

4、静态常量和非静态常量

   (1)静态成员变量又称为类变量。

    (2)非静态成员变量又被称为实例变量。

    (3) 实例变量和类变量的区别

a、存放位置

        类变量随着类的加载而存在于方法区中。

        实例变量随着对象的建立而存在于堆内存中。

 b、生命周期

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

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

5、静态的利弊

(1)利

    可以直接被类名调用。

(2)弊

    存放在内存里, 生命周期过长。
    访问出现局限性。(静态虽好,只能访问静态)

    对对象的共享数据进行单独空间的存储,节省空间。

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

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

class Student  
{  
    private int id; //定义私有变量id; 
    private static int studentId = 1; //定义静态 int studentId; 
    //获取id的访问器  
    public int getId()  
    {  
        return id;  
    }  
    public void setId()  
    {  
        id = studentId;  
        studentId++;  
    }  
}

6、静态的应用

/** 
这是一个可以对数组进行相关操作的工具类,该类提供了取数组的最值、排序等功能。 
@author 王永华
@version V1.8
*/  
//类名权限要最大才能创建说明书文档  
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]+"]");  
    }  
}  
    通过以上我们可以发现,一下将要解决的问题。

    (1) 当每个应用程序都有共同之处,可将其封装,提高其复用性。

   (2) 注意事项

    a. 对象时用于封装数据的;
    b. 对数据的操作方法,若没用到方法中特有的数据,则无需创建对象而占用多余的内存。

   (3)静态代码块

    a. 随着类的加载而执行,且优先于主函数;
    b. 只执行一次,类再创建对象,则不再执行,已经存在于内存中。
   格式:

static  
   {语句};

七、单例设计模式

1、概念

   解决某一问题最行之有效的方法,java中共有23种设计模式,其中单利设计模式就是其中一种

2、单例设计模式

   单例设计模式的作用:使一个类在内存中只存在一个对象。

3、单例设计模式的具体表现形式  

        单利设计模式其中具体表现有:饿汉式和懒汉式;其实是两中思维的碰撞。

(1)饿汉式

    特点:先初始化对象

class Single   
{  
    private Single(){}  
    private static Single s = new Single();  
    public static  Single getSingle()  
    {  
        return s;  
    }  
}  
  
class SingleText  
{  
    public static void main(String [] args)  
    {  
        Single s1 = Single.getSingle();  
        Single s2 = Single.getSingle();  
        if (s1==s2)  
            System.out.println(true);  
        else  
            System.out.println(false);        
    }  
}

(2)懒汉式

    特点:对象是方法被调用时,才初始化,这也叫对象的延时加载。

class Single   
{  
    private Single(){}  
    private static Single s = null;  
    public static Single getSingle()  
    {  
        if (s==null)   
            s = new Single();  
        return s;  
    }  
}  

class SingleText  
{  
    public static void main(String [] args)  
    {  
        Single s1 = Single.getSingle();  
        Single s2 = Single.getSingle();  
        if (s1==s2)  
     System.out.println(true);  
        else  
     System.out.println(false);        
    }  
}

    相比之下,我个人理解,第1种会占用内存一些,第二种少占内存一些,更加贴和,却又存在线程的安全问题。总体而言饿汉式比懒汉式更可靠。    

    今天到这里吧,小伙伴们明天见。















  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值