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 实现类,而不需要修改依赖组件的代码。
Java面向基础概述和三大特性的更多相关文章
- Java基础-面向对象第三大特性之多态(polymorphism)
Java基础-面向对象第三大特性之多态(polymorphism) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.多态概述 多态是继封装,继承之后,面向对象的第三大特性,多态的 ...
- OC基础 类的三大特性
OC基础 类的三大特性 OC的类和JAVA一样,都有三大特性:继承,封装,多态,那么我们就来看一下OC中类的三大特性. 1.继承 继承的特点: (1)子类从父类继承了属性和方法. (2)子类独有的属 ...
- [.net 面向对象编程基础] (11) 面向对象三大特性——封装
[.net 面向对象编程基础] (11) 面向对象三大特性——封装 我们的课题是面向对象编程,前面主要介绍了面向对象的基础知识,而从这里开始才是面向对象的核心部分,即 面向对象的三大特性:封装.继承. ...
- [.net 面向对象编程基础] (12) 面向对象三大特性——继承
[.net 面向对象编程基础] (12) 面向对象三大特性——继承 上节我们说了面向对象的三大特性之一的封装,解决了将对同一对象所能操作的所有信息放在一起,实现统一对外调用,实现了同一对象的复用,降低 ...
- [.net 面向对象编程基础] (13) 面向对象三大特性——多态
[.net 面向对象编程基础] (13) 面向对象三大特性——多态 前面两节,我们了解了面向对象的的封装和继承特性,面向对象还有一大特性就是多态.比起前面的封装和继承,多态这个概念不是那么好理解.我们 ...
- Java面向对象概述和三大特性
Java 是面向对象的高级编程语言,类和对象是 Java 程序的构成核心.围绕着 Java 类和 Java 对象,有三大基本特性:封装是 Java 类的编写规范.继承是类与类之间联系的一种形式.而多态 ...
- Java基础—面向对象的三大特性
面向对象有三大特性分别是继承.封装和多态. (1)继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类 ...
- JAVA多线程-内存模型、三大特性、线程池
一.线程的三大特性 原子性.可见性.有序性 1)原子性,即一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行.原子性其实就是保证数据一致.线程安全一部分. 2)可见性,即 ...
- python基础(24):面向对象三大特性一(继承)
1. 继承 1.1 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继 ...
随机推荐
- MarkDown时序图
时序图 语法 ```sequence ``` 标题 title: 我是标题 对象 participant A participant B as b-alias 交互 sequence A->B: ...
- 启动elasticsearch报错的几种原因及解决方法
ERROR: [1] bootstrap checks failed [1]: max virtual memory areas vm.max_map_count [65530] is too low ...
- python:将网页图片保存到本地
1.requests库介绍 在python中,有一个非常好用的网络请求库requests,使用它可以发起网络请求,并获取网页返回的内容.同时,也可以进行网页图片下载 requests是使用Apache ...
- Web信息搜集
文件是转载原文https://www.freebuf.com/articles/web/204883.html 如有侵权 请联系 对一个网站挖掘的深浅来说,信息收集是非常的重要的,这篇文章主要分享本 ...
- Centos6 Tengine开启http2传输协议
1.前言 最近在优化网站的访问速度,为网站开启http2协议,这个协议有什么优点呢?如下: http2是下一代的传输协议,以后都会普遍用它,是一个趋势. http2有多路复用特性,意思是访问一个域名下 ...
- ThinkPHP5.1 反序列化利用链
笔记里直接复制出来的 1 composer直接获取框架代码 ➜ composer create-project --prefer-dist topthink/think tp5137 ➜ ...
- 使用Typescript重构axios(十三)——让响应数据支持泛型
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 使用Typescript重构axios(十九)——请求取消功能:实现第二种使用方式
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- Scrapy进阶知识点总结(五)——Settings
1.设置优先级 Scrapy中有不同层次的设置,其类型以及优先级如下(从高到低): 1.命令行命令中指定的设置 2.每个spider中的设置 3.scrapy项目中settings.py设置 4.命令 ...
- CentOS 6.4 configure error的解决方法
资料来源:http://blog.sina.com.cn/s/blog_62426dcf0100f2rz.html 虽然上面的文章是针对centOS 5写的,不过经测试也可用于centOS6.4. 自 ...