Java面向基础概述和三大特性

Java 是面向对象的高级编程语言,类和对象是 Java 程序的构成核心。围绕着 Java 类和 Java 对象,有三大基本特性:封装是 Java 类的编写规范、继承是类与类之间联系的一种形式、而多态为系统组件或模块之间解耦提供了解决方案。

  本文主要围绕这三大特性介绍一下 Java 面向对象、组件解耦的核心思想。

1、面向对象思想

  面向对象编程是当今主流的程序设计思想,已经取代了过程化程序开发技术,Java 是完全面向对象编程语言,所以必须熟悉面向对象才能够编写 Java 程序。

  面向对象的程序核心是由对象组成的,每个对象包含着对用户公开的特定功能和隐藏的实现部分。程序中的很多对象来自 JDK 标准库,而更多的类需要我们程序员自定义。

  从理论上讲,只要对象能够实现业务功能,其具体的实现细节不必特别关心。

  面向对象有以下特点:

  (1)面向对象是一种常见的思想,比较符合人们的思考习惯;

  (2)面向对象可以将复杂的业务逻辑简单化,增强代码复用性;

  (3)面向对象具有抽象、封装、继承、多态等特性。

  面向对象的编程语言主要有:C++、Java、C#等。

2、类和对象的关系

  类:

  对某类事物的普遍一致性特征、功能的抽象、描述和封装,是构造对象的模版或蓝图,用 Java 编写的代码都会在某些类的内部。类之间主要有:依赖、聚合、继承等关系。

  对象:

  使用 new 关键字或反射技术创建的某个类的实例。同一个类的所有对象,都具有相似的数据(比如人的年龄、性别)和行为(比如人的吃饭、睡觉),但是每个对象都保存着自己独特的状态,对象状态会随着程序的运行而发生改变,需要注意状态的变化必须通过调用方法来改变,这就是封装的基本原则。

3、封装思想

  核心思想就是“隐藏细节”、“数据安全”:将对象不需要让外界访问的成员变量和方法私有化,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,保证了数据的安全和程序的稳定。

  具体的实现方式就是:

  使用 private 修饰符把成员变量设置为私有,防止外部程序直接随意调用或修改成员变量,然后对外提供 public 的 set 和 get 方法按照开发者的意愿(可以编写一些业务逻辑代码,虽然很少这样做)设置和获取成员变量的值。

  也可以把只在本类内部使用的方法使用 private,这就是封装的思想,是面向对象最基本的开发规范之一。

  在此,我们有必要说一下 Java 的访问权限修饰关键字。Java 中主要有 private、protected、public 和 默认访问权限 四种:

  public 修饰符,具有最大的访问权限,可以访问任何一个在 CLASSPATH 下的类、接口、异常等。

  protected 修饰符,主要作用就是用来保护子类,子类可以访问这些成员变量和方法,其余类不可以。

  default 修饰符,主要是本包的类可以访问。

  private 修饰符,访问权限仅限于本类内部,在实际开发过程中,大多数的成员变量和方法都是使用 private 修饰的。

  

  Java 的访问控制是停留在编译层的,只在编译时进行访问权限检查,不会在类文件中留下痕迹。

  通过反射机制,还是可以访问类的私有成员的。

我们举个小例子:

public class MobilePhone {

    // 使用 private 关键字把成员变量私有化
    private String os;
    private String phoneNumber;
    private String brand;
    private double dumpEnergy;

    // 对外提供访问、设置成员变量的 public 方法
    // 这样就可以按照我们自己的意愿来访问、设置成员变量
    // 而且也有助于在方法内部对数据有效性进行验证
    public void setOs(String os){
        this.os = os;
    }
    public String getOs(){
        return this.os;
    }
    public void setPhoneNumber(String phoneNumber){
        this.phoneNumber = phoneNumber;
    }
    public String getPhoneNumber(){
        return this.phoneNumber;
    }
    public void setBrand(String brand){
        this.brand = brand;
    }
    public String getBrand(){
        return this.brand;
    }
    public void setDumpEnergy(double dumpEnergy){
        this.dumpEnergy = dumpEnergy;
    }
    public double getDumpEnergy(){
        return this.dumpEnergy;
    }

    // 发短信的方法,不需要做修改
    public void sendMessage(String message, String targetPhoneNumber){
        System.out.println("发给" + targetPhoneNumber + ", 内容是:" + message);
    }

    // 充电方法,不需要做修改
    public double charge(){
        System.out.println("正在充电, 剩余电量:" + dumpEnergy * 100 + "%");
        return dumpEnergy;
    }

    // 对外提供的开机方法
    public void startup(){
        System.out.println("正在开机......");

        // 调用私有开机方法
        startup2();

        System.out.println("完成开机");
    }

    // 私有的开机方法,封装开机细节
    private void startup2(){
        System.out.println("启动操作系统......");
        System.out.println("加载开机启动项......");
        System.out.println("......");
    }
}

 在实际的开发过程中,这样的封装方式已经成了 Java Bean 代码编写的规范。现在主流的框架在使用反射技术为对象赋值、取值时使用的都是 set 和 get 方法,而不是直接操作字段的值。

4、继承和类实例化过程

  (1)在多个不同的类中抽取出共性的数据和逻辑,对这些共性的内容进行封装一个新的类即父类(也叫做超类或基类),让之前的类来继承这个类,那些共性的内容在子类中就不必重复定义,比如 BaseDAO、BaseAction 等。

  * (2)Java 的继承机制是单继承,即一个类只能有一个直接父类。

  * (3)如果子类和父类有同名成员变量和方法,子类可以使用 super 关键字调用父类的成员变量和方法,上述使用方式前提是成员在子类可见。

  * (4)在调用子类构造方法时,会隐式的调用父类的构造方法 super()。如果父类没有无参构造方法,为了避免编译错误,需要在子类构造方法中显式的调用父类的含参构造方法。

  (5)子类创建时调用父类构造方法:子类需要使用父类的成员变量和方法,所以就要调用父类构造方法来初始化,之后再进行子类成员变量和方法的初始化。因此,构造方法是无法覆盖的。

  * (6)当子类需要扩展父类的某个方法时,可以覆盖父类方法,但是子类方法访问权限必须大于或等于父类权限。

  (7)继承提高了程序的复用性、扩展性,也是 Java 语言多态特征的前提。

  (8)在实际开发、程序设计过程中,并非先有的父类,而是先有了子类中通用的数据和逻辑,然后再抽取封装出来的父类。

  我们简单了解下类的实例化过程

  (1)JVM 读取指定 classpath 路径下的 class 文件,加载到内存,如果有直接父类,也会加载父类;

  (2)堆内存分配空间;

  (3)执行父类、子类静态代码块;

  (4)对象属性进行默认初始化;

  (5)调用构造方法;

  (6)在构造方法中,先调用父类构造方法初始化父类数据;

  (7)初始化父类数据后,显示初始化,执行子类的构造代码块;

  (8)再进行子类构造方法的特定初始化;

  (9)初始化完毕后,将地址赋值给引用

  为了说明上面的内容,我们来编写一个简单的例子,实际意义并不大,只是为了演示类继承实例化的过程。

  

/*
    父类
*/
class Parent {

    int num = 5;

    static {
        System.out.println("父类静态代码块");
        System.out.println();
    }

    {
        System.out.println("父类构造代码块1," + num);
        num = 1;
        System.out.println("父类构造代码块2," + num);
        doSomething();
        System.out.println();
    }

    Parent() {
        System.out.println("父类构造方法1," + num);
        num = 2;
        System.out.println("父类构造方法2," + num);
        doSomething();
        System.out.println();
    }

    void doSomething() {
        System.out.println("父类doSomething方法1," + num);
        num = 3;
        System.out.println("父类doSomething方法2," + num);
        System.out.println();
    }
}

/*
    子类
*/
class Child extends Parent {

    int num = 10;

    /*
        静态代码块,在类加载时执行
    */
    static {
        System.out.println("子类静态代码块");
        System.out.println();
    }

    /*
        构造代码块
    */
    {
        System.out.println("子类构造代码块1," + num);
        num = 11;
        System.out.println("子类构造代码块2," + num);
        doSomething();
        System.out.println();
    }

    Child() {
        System.out.println("子类构造方法1," + num);
        num = 12;
        System.out.println("子类构造方法2," + num);
        doSomething();
        System.out.println();
    }

    void doSomething() {
        System.out.println("子类doSomething方法1," + num);
        num = 13;
        System.out.println("子类doSomething方法2," + num);
        System.out.println();
    }

}

public class A {
    public static void main(String[] args) {
        Child child = new Child();
        child.num = 20;
        child.doSomething();
    }
}

输出:

父类静态代码块

子类静态代码块

父类构造代码块1,5
父类构造代码块2,1
子类doSomething方法1,0
子类doSomething方法2,13

父类构造方法1,1
父类构造方法2,2
子类doSomething方法1,13
子类doSomething方法2,13

子类构造代码块1,10
子类构造代码块2,11
子类doSomething方法1,11
子类doSomething方法2,13

子类构造方法1,13
子类构造方法2,12
子类doSomething方法1,12
子类doSomething方法2,13

子类doSomething方法1,20
子类doSomething方法2,13

5、多态、反射和组件解耦

  多态指允许不同类的对象对同一“消息”做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。可以用于消除类型之间的耦合关系,Spring 的核心就是多态和面向接口编程。

  (1)Java 中可以使用父类、接口变量引用子类、实现类对象;

  (2)在这个过程中,会对子类、实现类对象做自动类型提升,其特有功能就无法访问了,如果需要使用,可以做强制类型转换。

  Java 的反射技术和多态特性是框架开发、组件解耦的核心,在这方面,Spring 的 IOC 和 DI 为我们提供了一个极好的学习范例,Spring 的 IOC 使用反射技术创建、管理对象,DI 使用多态技术为组件注入依赖对象。

  在没有学习 Spring 之前,简单的解决方案是使用一个 .properties 文件保存程序中使用的接口、实现类类型键值信息,然后在程序中使用一个全局 Properties 对象保存这些信息,并且使用反射技术把这些实现类初始化、提供一个静态的方法获取指定接口的实现类对象,在组件中就可以使用依赖对象的键获取需要的对象。

  这样的方案带来的好处就是:当我们需要修改某个组件的实现方式时,比如把之前 JDBC 的 DAO 实现改为 Hibernate 实现,只要把这些新的实现类放到 classpath 下,把 .properties 文件对应接口的实现类类型改成新的 Hibernate 实现类,而不需要修改依赖组件的代码。

原文地址:https://www.cnblogs.com/donleo123/p/11617141.html

时间: 2024-10-07 14:13:35

Java面向基础概述和三大特性的相关文章

OC基础 类的三大特性

OC基础  类的三大特性 OC的类和JAVA一样,都有三大特性:继承,封装,多态,那么我们就来看一下OC中类的三大特性. 1.继承 继承的特点: (1)子类从父类继承了属性和方法. (2)子类独有的属性和方法不能被父类使用. (3)子类独有的属性和方法,不能够在子类之间互相使用. (4)子类能够重写父类的方法,子类调用该方法时:首先调用子类的方法,如果子类没有该方法,就调用父类的该方法. (5)子类对象指针可以转换成父类对象指针,但是父类对象指针不能够转换成子类对象指针. 三种权限变量的继承:

[.net 面向对象编程基础] (11) 面向对象三大特性——封装

[.net 面向对象编程基础] (11) 面向对象三大特性——封装 我们的课题是面向对象编程,前面主要介绍了面向对象的基础知识,而从这里开始才是面向对象的核心部分,即 面向对象的三大特性:封装.继承.多态. 1.封装概念 封装:每个对象都包含有它能进行操作的所有信息,这个特性称为封装.这样的方法包含在类中,通过类的实例来实现. 2.封装的优点 A.良好的封装能够减少耦合(比如实现界面和逻辑分离) B.可以让类对外接口不变,内部可以实现自由的修改 C.类具有清晰的对外接口,使用者只需调用,无需关心

Java基础—面向对象的三大特性

面向对象有三大特性分别是继承.封装和多态. (1)继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类).派生类可以从它的基类那里继承方法和实例变量,并且子类可以修改或增加新的方法使之更适合特殊的需要. (2)封装:封装是指将客观事物抽象成类,每个类对自身的数据和方法实行保护.类可以把自己的数据和方法只让可信的类或者对象

Java基础知识面向对象三大特性

面向对象三大特性:一 封装:概念:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式.好处:将变化隔离;便于使用;提高重用性;安全性.封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问.二 继承好处:1:提高了代码的复用性.2:让类与类之间产生了关系,提供了另一个特征多态的前提.注意:子类中所有的构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super();如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过supe

[java学习笔记]java语言基础概述之数组的定义&常见操作(遍历、排序、查找)&二维数组

1.数组基础 1.什么是数组:           同一类型数据的集合,就是一个容器. 2.数组的好处:           可以自动为数组中的元素从零开始编号,方便操作这些数据. 3.格式:  (一旦创建,必须明确长度)          格式1:              元素类型   [ ]  数组名  =  new  元素类型  [元素个数即数组的长度]:              示例:int[] array = new int[5];          格式2:           

[java学习笔记]java语言基础概述之内存的划分&堆和栈

1.内存的划分 1.寄存器         cpu处理 2.本地方法区        和所在系统相关 3.方法区 4.栈内存 5.堆内存 2.栈和堆 1.栈:      存储的都是局部变量.而且变量所属的作用域一旦结束,就释放该变量.      栈中的变量生命周期都很短,更新速度会很快. 局部代码块:限定局部变量的生命周期.局部代码块一旦执行结束,里面的变量就会被释放. 2.堆      存储的是数组和对象.凡是new建立的,都会存在堆里.      特点: 每一个实体都有首地址值. 堆内存中的

[java学习笔记]java语言基础概述之函数的定义和使用&函数传值问题

1.函数 1.什么是函数? 定义在类中的具有特定功能的一段独立小程序. 函数也叫做方法 2.函数的格式 修饰符   返回值类型    函数名(参数类型  形式参数1, 参数类型  形式参数2-) {           执行语句(函数体);           return 返回值;       } 返回值类型:函数运行完成后输出的数据类型. 参数类型:是形式参数的数据类型. 形式参数:是一个变量,用于储存调用函数时传递给函数的实际参数. 实际参数:传递给形参的实际数据. return:结束函数

[java学习笔记]java语言基础概述之转义字符&break&continue

1.转义字符 \t:制表符 \n:回车 \b:退格 \r:回车 \":双引号 \\:反斜线(常用于文件路径的书写中)   windows系统中回车符其实是由两个符号组成的,\r\n linux系统中回车符是\n 2.break&continue break(跳出)语句:应用范围是选择结构(switch语句)和循环结构 continue(继续)语句:应用于循环结构 注意: 这两个语句离开应用范围是没有意义的,编译会报错. 这两个语句单独存在下面都不可以有语句,因为执行不到.一般使用if判断

Spring Boot 基础概述

上半年一直忙于工作,没有太多的时间去写文字,期间也比较关注 .net core 的发展,比较看好 asp.net core 的 OO 抽象设计,也参考了abp.zero 的设计.其实大多数情况平常的工作主要还是结合一些理论与技术框架快速实现:个人的时间就是成本,最近打算整理下 Spring Boot  的相关知识,也算是多一种选择吧 . 概述与目录 对于学习新的知识,我认为最快的方式就是先过一遍官方的文档,这一步很重要:后面再结合实际情况的运用就好了.所以我罗列了一些目录,应该覆盖了大多数的运用