当前位置:首页 >休闲 >Java基础:如何理解面向对象? 向对象也可以更具体

Java基础:如何理解面向对象? 向对象也可以更具体

2024-06-30 16:40:30 [百科] 来源:避面尹邢网

Java基础:如何理解面向对象?基础解面

作者:斯巴达人 开发 前端 面向对象中有四个特性,封装,何理继承,向对象多肽,基础解面抽象,何理Java利用这些特性来描述类和类与类的向对象关系。

本篇开始会从基础开始把每一个知识点讲明白讲透彻,基础解面旨在让每个知识点都能在工作中和面试中用的何理上。如果有讲的向对象不明白的地方欢迎公众号私信讨论,第一时间有问必答。基础解面

java的何理设计就是将java世界比作真实世界,一切事物都可以被某些类型定义,向对象每一个具体的基础解面事物都是类型下面的实体对象,类型可以更抽象,何理比如“鸟类”,向对象也可以更具体,比如“麻雀”,而一只活蹦乱跳的麻雀对象属于麻雀这个类型,也属于鸟类这个类型,而鸟类是麻雀类的抽象。

Java基础:如何理解面向对象? 向对象也可以更具体

真实的世界中每种类型的特点以及类与类的关系是生来就有的,就像是我们看到天上飞的我们就知道它是鸟类,而java世界毕竟不是真实世界,他需要通过定义规则来约束这些关系。

Java基础:如何理解面向对象? 向对象也可以更具体

面向对象中有四个特性,封装,继承,多肽,抽象,java利用这些特性来描述类和类与类的关系。

Java基础:如何理解面向对象? 向对象也可以更具体

一、类

虽然java是模拟真实世界,但是java对类的定义是开放,程序员可以按照自己想象任意定义类,但是类的定义和现实世界又是一样的,我们在描述一个鸟类的时候,一般是说鸟有羽毛,五颜六色,会飞等等,但是归根结底是在阐述鸟的外观和技能,而在java中外观描述和技能对应的是类中的成员属性和成员方法。

二、对象

java中通过new关键字创建的就是一个具体的对象,它具备所属类的所有属性和方法,它可以在适当的地方被操作。

三、面向对象的特性

1.封装

封装也叫作信息隐藏或者数据访问保护,我们用一个非常通俗的现实例子来说明下:

public class bank {     private String id;    private long createTime;    private BigDecimal balance;    private long balanceLastModifiedTime;}

这是一个银行存款的例子,在存款的时候有存款时间,存款后的余额,余额更改时间,如果这几个属性是public修饰,那么其他类都可以访问这几个属性,并且对其任意修改,这是不安全的,封装的目的把属性的修改权限私有化,比如时间只有内部可以改动,不需要对外开放,对于余额的改动银行依赖于存款人存多少钱,所以可以提供一个带入参的函数入口,类似于存款人把钱给到银行,由银行人员进行余额的变动,这是把权限最小化,尽可能增强安全性,通过有限的方法暴露必要的操作,我们代码中的get set方法就是封装的最简体现。

2.继承

继承是指子类继承父类,语法机制:extends

public class A extends D

一旦达成继承关系,子类就会拥有父类非private修饰的属性和方法。 并且子类可以拥有自己独有的属性和方法,同时子类还可以用自己的方式实现父类的方法,即重写。

一个父类可以被多个子类继承,但是一个子类不能继承多个父类。

继承让代码可以复用,把子类共有的方法抽离到父类中实现,由子类来继承父类,从而达到代码精简。

关于继承还有两种特殊的继承:实现接口和继承抽象类。

我们先来了解下接口和抽象类。

(1) 抽象类

public abstract class A

一个普通的类如果被abstract修饰,就是一个抽象类,抽象类相对于普通类的特点如下:

  • 可以存在abstract修饰的方法,即抽象方法,被abstract修饰的方法不能用private、static、synchronized、native等访问修饰符修饰,并且没有实现体。
  • 不能实例化,只能被子类继承
  • 如果子类继承了抽象类,并且实现了抽象类的所有抽象方法,那么子类是一个具体的类,如果没有全部实现其抽象方法,则子类也是一个抽象类
  • 抽象类可以有构造方法,目的是让子类来调用构造方法初始化

(2) 接口

接口是一种特殊的抽象类,语法机制:interface

public interface B

接口其实就是一种特殊的抽象类,相对于抽象类不同的地方是:

  • 只能被实现,其实现也是一种特殊的继承,却别是继承只能单继承,而实现可以多实现。
  • 接口中默认所有的方法都是抽象方法。
  • 接口中定义的成员变量默认是public static final,即只能够有静态的不能被修改的数据成员,而且必须赋初值。
  • 一个类可以实现多个接口,一定程度上弥补了不能多继承的问题。
  • java中类可以继承类,也可以实现接口,接口也可以继承接口,而且接口继承接口可以多继承,即一个接口可以用关键字extends继承多个接口。

对于接口和抽象类的应用如何理解:

结合面向对象思想来理解,抽象类是类的溯源产物,比如:幼年猫-猫-猫科-动物,是一个类群里不断向上溯源就是抽象;而接口是对行为的分组,比如吃饭,睡觉,玩游戏。

那么在日常应用中,应该怎么应用呢?

从设计的角度讲,接口往往被用来定义一组行为,举个例子:

public class 鸟cry();
public class 鸭 extends 鸟cry(){   嘎嘎嘎}
public class 鸡 extends 鸟cry(){   吱吱吱}
public class 乌鸦 extends 鸟cry(){   喳喳喳}

如上代码,每种鸟都有自己独特的叫声,每种鸟都要重写cry方法,没有办法将叫这个行为抽象到父类中,也就无法利用父类实现代码复用,增加了代码的复杂性和开发工作量。

如果每种鸟都有自己独特的叫声,那每个鸟类都要重写cry方法也是没有办法但是必须这么做的事情。但事实上,鸟类的数量远远大于叫的方式的数量,也就是说,可能一百种鸟的叫声都是吱吱吱,一百种鸟的叫声都是咕咕咕,这种情况下,就可以通过接口来设计了。

就是用接口定义行为,由具体的行为类实现接口,每个鸟类再将叫的行为委托给行为类实现。

public interface cry
public class Zhizhizhi implements crycry(){ 吱吱吱}
public class Gagaga implements crycry(){ 嘎嘎嘎}
public class 鸭 extends 鸟Gagaga gagaga;cry(){   gagaga.cry();}
public class 鸡 extends 鸟Zhizhizhi zhizhizhi;cry(){   zhizhizhi.cry();}

如上代码,将行为从具体的类中分离出来单独定义为行为类,具体类和行为类以组合在一起,这样就可以复用代码。

所有的行为都需要这样设计吗?并不是,只有当前类独有的行为可以在当前类中单独实现。而那些变化多端的行为就要以这样方式设计。

从开发的角度讲,接口往往用于隔离接口和实现达到解耦的效果

日常开发中我们设计一个功能,往往是以接口的形式对外暴露,不暴露实现,这样的设计为了隔离接口和具体的实现,提高代码的扩展性。

3.多态

多态是指子类可以替换父类,父类的引用可以指向子类,我们直接用代码来说明:

public class DynamicArray {     private static final int DEFAULT_CAPACITY = 10;  protected int size = 0;  protected Integer[] elements = new Integer[DEFAULT_CAPACITY];  public int size() {    return this.size;  }  public Integer get(int index) {    return elements[index];  }  public void add(Integer e) {    elements[size++] = e;  } } public class SortedDynamicArray extends DynamicArray {   @Override  public void add (Integer e) {    int i;   for (i = size - 1; i >= 0; --i) {     if (elements[i] > e) {      elements[i + 1] = elements[i];    } else {      break;    }   }   elements[i + 1] = e;   ++size;  } } public class Example {   public static void test(DynamicArray dynamicArray) {    dynamicArray.add(5);   dynamicArray.add(1);   dynamicArray.add(3);   for (int i = 0; i < dynamicArray.size(); ++i) {     System.out.println(dynamicArray.get(i));   }  }  public static void main(String args[]) {    DynamicArray dynamicArray = new SortedDynamicArray();   test(dynamicArray);  } }
public interface Iterator {   String hasNext();  String next();  String remove(); } public class Array implements Iterator {     private String[] data;  public String hasNext() {  ...}  public String next() {  ...}  public String remove() {  ...} } public class LinkedList implements Iterator {   private LinkedListNode head;  public String hasNext() {  ...}  public String next() {  ...}  public String remove() {  ...} }
public class Demo {   private static void print(Iterator iterator) {    while (iterator.hasNext()) {     System.out.println(iterator.next());   }  }  public static void main(String[] args) {    Iterator arrayIterator = new Array();   print(arrayIterator);   Iterator linkedListIterator = new LinkedList();   print(linkedListIterator);  } }

上面两个案例中最关键的代码:

DynamicArray dynamicArray = new SortedDynamicArray();Iterator arrayIterator = new Array();

这两行代码都是用父类来接收子类,其实这就是多肽,但是要达到这样的目的是要依赖于“继承”或者“实现”,正如上面的代码一样。

多态特性能提高代码的可扩展性和复用性。

在那个例子中,我们利用多态的特性,仅用一个print()函数就可以实现遍历打印不同类型(Array、LinkedList)集合的数据。当再增加一种要遍历打印的类型的时候,比如HashMap,我们只需让HashMap实现Iterator接口,重新实现自己的hasNext()、next()等方法就可以了,完全不需要改动print()函数的代码。所以说,多态提高了代码的可扩展性。

总结

Java的基础就是面向对象思想,支撑面向对象思想是:封装,继承,多肽,抽象,接口,后续的设计模式都是建立在这些基础特性上面,要想开发出高质量代码必须先掌握基础。

责任编辑:赵宁宁 来源: 码农本农 Java面向对象

(责任编辑:百科)

    推荐文章
    热点阅读