zoukankan      html  css  js  c++  java
  • JavaSE(一)之类与对象

    在java中经常被提到的两个词是类与对象,实质上可以将类看作是对象的载体,它定义了对象所具有的功能。学习java语言必须要掌握类与对象,这样可以从深层次去理解java这种面向对象语言的开发理念,从而更好的掌握java编程思想与编程方式。

    OOP概述

    Java的编程语言是面向对象的,采用这种语言进行编程称为面向对象编程(Object-Oriented Programming, OOP)。

    面向对象的特征

    抽象(abstract)

    抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征。
    例如苹果、香蕉、生梨、葡萄、桃子等,它们共同的特性就是水果。得出水果概念的过程,就是一个抽象的过程。
    要抽象,就必须进行比较,没有比较就无法找到共同的部分。
    共同特征是指那些能把一类事物与他类事物区分开来的特征,这些具有区分作用的特征又称本质特征。
    因此抽取事物的共同特征就是抽取事物的本质特征,舍弃不同特征。
    所以抽象的过程也是一个裁剪的过程,不同的、非本质性的特征全部裁剪掉了。
    所谓的共同特征,是相对的,是指从某一个刻面看是共同的。
    比如,对于汽车和大米,从买卖的角度看都是商品,都有价格,这是他们的共同的特征,而从其他方面来比较是,他们则是不同的。
    所以在抽象时,同与不同,决定于从什么角度上来抽象。抽象的角度取决于分析问题的目的。
    在软件开发过程中,识别稳定的需求、识别核心的需求、识别概念性的需求、设计系统的架构、定义系统中构件之间的接口关系等等都是抽象的过程,都是反应系统的本质特征的过程。
    抽象的,才是稳定的,才是永恒的。 抽象的反义词是具体。人员往往会说:“你讲的太抽象了,能不能讲的具体一点?”
    在开发语言中,有抽象类,有具体类,具体类可以继承自抽象类,可以实例化。抽象类可以派生出众多的不同的具体类。
    所谓:“道生一,一生二,二生三,三生万物”。系统的稳定体现在抽象类,系统的变化体现在具体类。抽象类的层次要高于具体类。
    系统因抽象而稳定,因抽象而生动。

    封装(Encapsulation)

    封装是面向对象编程的核心思想。将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。例如:用户使用计算机时,只需要使用手指敲击键盘就可以实现一些功能,无需知道计算机内部是如何工作的,即使可能知道计算机的工作原理,但在使用计算机的时候也并不完全依赖计算机工作原理这些细节。

    采用封装的思想保证了类内部数据结构的完整性,应用该类的用户不能轻易地直接操作此数据结构,只能执行类允许公开的数据。这样避免了外部操作对内部数据的影响,提高了程序的可维护性。

    继承(inheritance)

    当处理一个问题时,可以将一些有用的类保留下来,在遇到同样问题时拿来复用。例如:我们通过抽象创建一个鸟类,这个类包含所有鸟都有的一些特征,比如:都有嘴,眼睛,或翅膀... ...,并且有一些共有的行为,如:都会吃东西,会飞... ...,现在需要创建一个信鸽来完成送信的行为,信鸽也属于鸟类,拥有鸟的一些共有特征,眼睛,会飞之类的。这时我们就可以通过信鸽类继承鸟类的方式,来获取共有的这些属性和行为而不需要在信鸽类中重新定义那些共有的属性和行为(眼睛,会飞... ...),但并不是所有的鸟都会送信,所以我们在信鸽类中再添加一些信鸽具有的独特的属性和行为。信鸽类保留了鸟类的属性和行为,这样就节省了定义鸟和鸽子共同具有的属性和行为的时间,这就是继承的基本思想。

    1. 继承可以复用已有代码,缩短开发时间,提高效率,减少系统在使用过程中出现错误的几率。
    2. 新类继承了原始类后,新类就继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类),并且派生类(子类)中可以修改或增加新的方法使之更适合特殊的需要。

    多态(polymorphism)

    所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

    以图形类(父类)为例来说明多态,每个图形都有绘画自己的能力,这个能力可以看作是该类具有的行为,如果将子类的对象统一看作是父类的实例对象,这样在绘制图形时,简单地调用父类也就是图形类绘制图形的方法即可绘制任何图形,这就是多态最基本的思想。如下:

    图形类 a = new 长方形;

    图形类 b = new 正方形;

    图形类 c = new 三角形;

    我们只是通过图形类这一个父类就能够引用不同的子类,这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。

    类与对象和对象与引用的关系

    类与对象的关系

    类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物.
    

    例如:我们生活中所说的词语:动物、植物、手机、电脑等等,这些也都是抽象的概念,而不是指的某一个具体的东西。

    例如: Person类、Room类、Car类等,这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为

    对象是抽象概念(类)的具体实例
    

    例如:长方形,正方形,三角形就是图形类的一个具体实例,信鸽就是鸟类的具体实例,展现出功能的是具体的实例,而不是一个抽象的概念。

    对象与引用的关系

    引用"指向"对象
    

    java号称一切皆为对象,但java中数据类型有基本数据类型和引用数据类型,基本数据类型暂时不谈,java中的对象都是引用数据类型。在程序中,创建出对象后,直接使用并不方便,所以一般会用一个引用类型的变量去接收这个对象,这个就是所说的引用指向对象.

    图形类 a = new 长方形;
    
    图形类 b = new 正方形;
    

    = 后面的分别指创建对象,而a,b其实只是引用,并不存储对象而是指向对象。但我们通常都会忽略这一点,称对象a,对象b。

    引用只是存储了对象的地址而已,通过地址找到后面的对象;
    

    创建与初始化对象

    使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
    

    那么对main方法中的以下代码:

    Student s = new Student();

    1. 为对象分配内存空间,将对象的实例变量自动初始化默认值为0/false/null。(实例变量的隐式赋值)
    2. 如果代码中实例变量有显式赋值,那么就将之前的默认值覆盖掉。(之后可以通过例子看到这个现象)例如:显式赋值private String name = "tom";
    3. 调用构造器;
    4. 对象内存地址值赋值给变量。(=号赋值操作)

    构造器

    类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。
    

    构造器有以下两个特点:

    1. 必须和类的名字相同;
    2. 必须没有返回类型,也不能写void。

    构造器的作用:

    1. 用new创建对象的时候必须使用类的构造器;
    2. 造器中的代码执行后,可以给对象中的属性初始化赋值。

    构造器重载:

     除了无参构造器之外,很多时候我们还会使用有参构造器,在创建对象时候可以给属性赋值.
    
    public class Student{
    	 
        private String name;
           
        public Student(String name){
            his.name = name;
        }
    }
    

    构造器之间的调用:

    使用this关键字,在一个构造器中可以调用另一个构造器的代码。
    
    注意:this的这种用法不会产生新的对象,只是调用了构造器中的代码而已.一般情况下只有使用new关键字才会创建新对象。
    
    public class Student{
    	 
        private String name;
        
        public Student(){
            this();
         }
         
        public Student(String name){
            this.name = name;
        }
    }
    

    默认构造器:

    在java中,即使我们在编写类的时候没有写构造器,那么在编译之后也会自动的添加一个无参构造器,这个无参构造器也被称为默认的构造器。
    

    例如:

    public class Student{

    }

    main:

    //编译通过,因为有无参构造器
    

    Student s = new Student();

    但是,如果我们手动的编写了一个构造器,那么编译后就不会添加任何构造器了
    

    例如:

    public Student(String name){
        this.name = name;
     }
    

    main:

    //编译失败,因为没有无参构造器
    

    Student s = new Student();

  • 相关阅读:
    AGC037F Counting of Subarrays
    AGC025F Addition and Andition
    CF506C Mr. Kitayuta vs. Bamboos
    AGC032D Rotation Sort
    ARC101F Robots and Exits
    AGC032E Modulo Pairing
    CF559E Gerald and Path
    CF685C Optimal Point
    聊聊Mysql索引和redis跳表
    什么是线程安全
  • 原文地址:https://www.cnblogs.com/J-Simon/p/10857042.html
Copyright © 2011-2022 走看看