Java 类与对象的介绍

一、面向对象简述。
面向对象是一种现在最为流行的程序设计方法,谈到面向对象就不得不提及面向过程。
这是两种不同的程序设计方法,常见的c语言用的是面向过程,而java、c++用的是面向对象。
对两种思想抽象地定义,
面向过程是围绕功能进行的,为每一个功能写一个函数,需要考虑其中的每一个细节,以步骤划分;
而面向对象则像是组装,先确定一个系统是由哪些对象组成,再分别去设计这些对象,将它们像零件一样组装起来形成有完整功能的系统。
再具体举一个常用的例子:用这两种方法分别实现“把大象放进冰箱”。
面向过程:肢解大象-打开冰箱-放入大象-关闭冰箱
面向对象:大象(肢解功能、移动功能)、冰箱(打开功能、装载功能、关闭功能)。

面向对象的三大特性。
(1)封装:保护内部的操作不被破坏; 
(2)继承:在原本的基础之上继续进行扩充; 
(3)多态:在一个指定的范围之内进行概念的转换。

二、类与对象的基本概念

类与对象时整个面向对象中最基础的组成单元。

类:是抽象的概念集合,表示的是一个共性的产物,类之中定义的是属性和行为(方法); 
对象:对象是一种个性的表示,表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性来区分不同对象。
比如说:人类是一个类,每一个人是类中的一个对象,每个人都有身高,体重,性别,外貌等等的属性。
在编程设计中,我们需要定义一个类,再给对应的类定义具体对象。

三、类与对象的定义和使用

类定义范式:

class 类名称{
      属性;
      行为;
}

定义Person类:

class Person{
      String name;//名字
      int height;//身高
      int age;//年龄
      public void walk(){
             System.out.print(name+"会走路");
      }  //走路
      public void tell(){
             System.out.print("名字:"+name+";"年龄:"+age);
      }
}

类定义完成之后,无法直接使用。如果要使用,必须依靠对象,对象的产生格式(两种格式)如下:

(1)格式一:声明并实例化对象

类名称 对象名称 = new 类名(); //格式
Person person = new Person();//Person实例

(2)格式二:先声明对象,再实例化对象

类名称 对象名称 = null;
对象名称 = new 类名(); //格式

Person person = null;
person = new Person(); //Person实例

 不同于int、String、char等基本数据类型,类属于引用数据类型,而引用数据类型在使用时需要用内存空间的分配和使用,关键字new就是用来分配内存的。

实例化一个对象后,可以用关键字"."对对象进行类的操作,比如定义属性具体值,使用方法。

对象名.属性名 = 具体值;
对象名.方法名();

person.age = 18;
person.walk();

接下来用在eclipse实践一下这两种实例化对象的方法。

格式一:

package com.alex.classtest;

class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = new Person() ;// 声明并实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}

运行结果:

姓名:张三,年龄:30

格式二:

package com.alex.classtest;

class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = null;//声明对象
            per = new Person() ;//实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}

运行结果:

姓名:张三,年龄:30

我们可以发现,得到的结果是一样的。那么这两种方式的区别在哪呢?

说到这里就必须从内存的角度来分析。

首先,给出两种内存空间的概念: 
(1)堆内存:保存对象的属性内容。堆内存需要用new关键字来分配空间; 
(2)栈内存:保存的是堆内存的地址(在这里为了分析方便,可以简单理解为栈内存保存的是对象的名字)。

任何情况下,只要看见关键字new,都表示要分配新的堆内存空间,一旦堆内存空间分配了,里面就会有类中定义的属性,并且属性内容都是其对应数据类型的默认值。

上面两种对象实例化对象方式内存表示如下:

两种方式的区别在于①②,第一种声明并实例化的方式实际就是①②组合在一起,而第二种先声明然后实例化是把①和②分步骤来。

如果使用了没有实例化的对象,则会程序运行结果会报错。

package com.alex.classtest;

class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = null;//声明对象
            //per = new Person() ;//实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}

运行结果:

Exception in thread "main" java.lang.NullPointerException
    at com.wz.classandobj.TestDemo.main(TestDemo.java:15)

错误信息表示的是“NullPointerException(空指向异常)”。是因为程序只声明了Person对象,但并没有实例化Person对象(只有了栈内存,并没有对应的堆内存空间),程序在编译的时候不会出现任何的错误,但是在执行的时候出现了上面的错误信息。

四、对象引用传递初步分析

引用传递定义上指的是同一块堆内存空间,可以同时被多个栈内存所指向,不同的栈可以修改同一块堆内存的内容。

也就是说同一个对象的属性内存被两个不同命名的对象共同使用。

看下面实例

class Person {
         String name ;
         int age ;
         public void tell() {
                   System.out.println("姓名:" + name + ",年龄:" + age) ;
         }
}
public class TestDemo {
         public static void main(String args[]) {
                   Person per1 = new Person() ;         // 声明并实例化对象
                   Person per2 = new Person() ;
                   per1.name = "张三" ;
                   per1.age = 20 ;
                   per2.name = "李四" ;
                   per2.age = 30 ;
                   per2 = per1 ;// 引用传递
                   per2.name = "王五" ;
                   per1.tell() ;
         }
}
 

输出的结果是:

姓名:王五,年龄:20

在这个过程中,内存空间是这样变化的:

垃圾:指的是在程序开发之中没有任何对象所指向的一块堆内存空间,这块空间就成为垃圾,所有的垃圾将等待GC(垃圾收集器)不定期的进行回收与空间的释放。

五、面向对象的封装性

在定义类时,在class或者属性变量之前加上修饰词public、private、default、protected表示它的被访问权限。

先看属性变量没有修饰词也就是默认(default)的时候,

class Book{

    String title;
    double price;

    public void getInfo(){
        System.out.println("图书的名称:"+title+" 图书的价格:"+price);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Book book = new Book();
            book.title = "Quanta";
            book.price = 99;
            book.getInfo();
        }
}

输出的结果是:

图书的名称:Quanta 图书的价格:99

当属性变量修饰词为private时:

class Book{

    private String title;
    private double price;

    public void getInfo(){
        System.out.println("图书的名称:"+title+" 图书的价格:"+price);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Book book = new Book();
            book.title = "Quanta";
            book.price = 99;
            book.getInfo();
        }
}

运行结果:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
    The field Book.title is not visible
    The field Book.price is not visible

    at com.wz.classandobj.TestDemo.main(TestDemo.java:16)

也就是在加入private修饰词后无法再Book类的外部直接调用它的属性了。

那么如何在类外部访问Book类内的private(私有)变量呢?这时候可以用到setter、getter方法。

为Book类定义属性相应的setter和getter方法,以Book类为例:

class Book{

    private String title;
    private double price;

    public void setTitle(String title){
        this.title = title;
}
    public String getTitle(){
        return title;
}

    public void setPrice(double price){
        this.price = price;
}
    public double getPrice(){
        return price;
}
    public void getInfo(){
        System.out.println("图书的名称:"+title+" 图书的价格:"+price);
    }
}

class TestDemo {
        public static void main(String args[]) {
            Book book = new Book();
            book.title = "Quanta";
            book.price = 99;
            book.getInfo();
        }
}

猜你喜欢

转载自blog.csdn.net/weixin_41276585/article/details/81504546