java 的 四 个 基 本 特 性 ——封装 继承 多态 抽象

简介:

java 的 四 个 基 本 特 性 ——封装 继承 多态 抽象

赶上明天就还是五一c小长假了,准备在这几天写几篇原创文章,供大家一起学习。

首先今天就来好好地唠一唠,到底java的那几个特性都是什么呢?到底怎么用呢?相信一定有一些小白对此会有些懊恼,没关系的,谁还不是从那个时候过来的呢!接下来我来一步一步的由潜到深的谈一谈我的看法,下面是我要说的内容

1.总体概括
2.概念的理解
3.代码示例并且分析
4.个人心得总结
1.总体概括
sequenceDiagram
封装->>继承: java的四个基本特性
多态->>抽象: java的四个基本特性
2.概念的理解
[1] 封装:

  • 在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。
    封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。
封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
适当的封装可以让程式码更容易理解与维护,也加强了代码的安全性。
通俗一点的可以这么理解,其实生活中有很多例子的,我来打几个比方,

例如:我们都使用果QQ这个聊天软件的,那么咱们要是想要使用它的话就必须要先注册

,等注册好的时候下次我们在直接输入我们自己设定的密码就可以了,不需要进行其他的操作

这个过程其实就是把QQ里面的数据给封装起来了,防止用户随

意更改,只有程序员才可以,这样他便可以保护程序的安全性

也就是说用户不需要直到QQ他是怎么执行的,内部是怎么实现的,对用户进行隐藏起来了

还有一种解释也可以说明:比如说个人计算机有很多组件——CPU 内存  磁盘  风扇  等等... 

我们不需要直到他的个个组件之间是怎么联系的,只要知道他们的个个功能是如何实现的就可以了

生活中的例子其实有很多很多 我就不一一说了。(要是还不明白可以私信或者评论区留言)

[2] 继承
继承”(Inheritance),
继承是指一个对度象直接使用另一对象的属性和方法。事实上,我们遇到的很多实体都有继承的含义。例如,问若把汽车看成一个实体,它可以分成多个子实答体,如:卡车、公共汽车等。这些版子实体都具有汽车的特性,权因此,汽车是它们的"父亲",而这些子实体则是汽车的"孩子"(但是孩子也会有自己新产生的特征)。子类是父类的特殊化,也就是子类的实例(对象)一定是父类的实例 ,但是反过来不一定成立{比如说:一个圆他一定是几何图形,但反过来几何图形他不一定就是圆呀!还会有很多的呀}
同样也说一个通俗易懂的例子:比如说,你家的家谱图,这其实就是一个很明显的一个继承关系

你的爸爸继承了你的爷爷(也就是子类继承父类),那么你的爸爸肯定会有可你爷爷相同的特征,但是呢! 你一定会发现你有一些特征是不同于你的爷爷的(当然也不同于你的奶奶),你会有你自己独一无二的特征,这就是继承的关系
[3] 多态

  • 概念:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。简单的说:就是用父类的引用指向子类的对象(变量)。
    原因:我们知道,封装可以隐藏实现细节,使得代码模块化;

继承可以扩展已存在的代码模块(类);
它们的目的都是为了代码重用。而多态除了代码的复用性外,还可以解决项目中紧偶合的问题,提高程序的可扩展性.。

耦合度讲的是模块模块之间,代码代码之间的关联度,通过对系统的分析把他分解成一个一个子模块,子模块提供稳定的接口,达到降低系统耦合度的的目的,模块模块之间尽量使用模块接口访问,而不是随意引用其他模块的成员变量。

有两个好处: 1. 应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。//继承 2. 派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。//多态的真正作用, 可以用在方法的参数中 和 方法的返回类型中。 (子类变量引用父类的变量)
[4] 抽象:
就是把一个对象分析出各个属性, 来替代表达的手法 。
抽 就是抽离;象 ,表复象。表示出来的部分
比如一棵树。整个一看我们就知道是树,但是具体是为什么呢

这制样就要拿树和其它东西比出不一样的地方,这些地方就是抽象出来的。

抽象出来的东西脱离了树本身,也就变得没有意义,但是组合起来百就是树的概念。

比如一棵树,10米高,树皮粗糙,树叶是针形,树干很直,等等。这些属性组合起来会感觉是一颗松树。但是单独说 10 米,没有对象的话,就不知道这个是说的什么东西。
编程上将对象抽象化是很有用的一个方法,能将枯燥的数据与单一度对象对应起来,这样易于理解,也便于编程。

例如在编写学员管理系统。

学生的定义,首先要有名字,再有性别,问再有学号,等等等等。这些就是抽象出来的属性
3.代码示例并且分析
[1] 多态
public class Main {

public static void main(String[] args) {
    // 给一个有普通收入、工资收入和享受国务院特殊津贴的小伙伴算税:
    Income[] incomes = new Income[] {
        new Income(3000),
        new Salary(7500),
        new StateCouncilSpecialAllowance(15000)
    };
    System.out.println(totalTax(incomes));
}

public static double totalTax(Income... incomes) {
    double total = 0;
    for (Income income: incomes) {
        total = total + income.getTax();
    }
    return total;
}

}

class Income {

protected double income;

//构造方法

public Income(double income) {
    this.income = income;
}

//定义一个方法

public double getTax() {
    return income * 0.1; // 税率10%
}

}
//子类Salary继承父类Income
class Salary extends Income {

//构造方法
public Salary(double income) {
    //super调用了继承的Salary中的构造方法
    super(income);
}

@Override
public double getTax() {
    if (income <= 5000) {
        return 0;
    }
    return (income - 5000) * 0.2;
}

}

class StateCouncilSpecialAllowance extends Income {

public StateCouncilSpecialAllowance(double income) {
    super(income);
}

@Override
public double getTax() {
    return 0;
}

}

输出:800.0
观察totalTax()方法:利用多态,totalTax()只需和income来打交道它完全不需要知道要StateCouncilSpecialAllowance和Salary的存在,就可以完全计算出得到的税,如果我们要增加一种稿费的收入,只需要重income中派生出来,然后正确覆盖getTax方法()就可以,把新的类型传入给getTax()就可以了
,不需要在重新修改代码

可以看出:多态是一个多么强大的功能,就是允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码

[2] 继承
public class Bike {

int speed;
int brand;
int colornum;
//构造方法
Bike(){
    System.out.println(" call bike constructor");
}
public void speedUp() {
    speed = 0;
    System.out.println(" too slow");
}
public void presshorn() {
    System.out.println(" I am riding the bike");
}

}

public class SpeedBike extends Bike{

/**
 * super可以调用数据成员及其构造方法
 */
SpeedBike(){//子类的构造方法
    super();
    super.colornum=12;//子类调用数据成员
    super.presshorn();
    System.out.println("call bike construction");    
}
public void ride() {
    System.out.println("I am riding the bike");
}
/**
 * super可以调用父类的方法
 */
public void speedUp() {
    super.speedUp();
    speed+=10;
    System.out.println("so fasyt! ," + " my speed is " + speed + " now");
}

}

public class DemoBike{

public static void main(String[] args) {
    SpeedBike aride = new SpeedBike();
            aride.presshorn();
            aride.speedUp();
            aride.ride();
}

}

输出:
call bike constructor
I am riding the bike
call bike construction
I am riding the bike
too slow
so fasyt! , my speed is 10 now(这个输出代码就是覆盖重写了父类的方法)
I am riding the bike

[3] 抽象
如果一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract来实现,因为无法执行抽象方法,因此这个类必须申请为抽象类
例如:Person 类定义了抽象方法run(),那么,在实现子类Student的时候,就必须覆盖run()方法

public class Main {

public static void main(String[] args) {
    Person p= new Student();
    p.run();
}

}
abstract class Person() {

public abstract void run();

}
class Student extends Person{

@overriding
public void run() {
    System.out.println("Student . run");
}

}

[4] 封装
package com.fengzhuang;
class Car{

private String name;//私有成员,名称
private String color;//私有成员,颜色
private String size;//私有成员,大小 
//得到String类型名字的方法,最后return 返回去
public String getName(){
    return name;
}
public String getColor(){
    return color;
}
public String getSize(){
    return size;
}
//因为方法名和参数名相同,所有用this
public void setName(String name){
    this.name=name;
}
public void setColor(String color){
this.color=color;
}
public void setSize(String size){
this.size=size;
}

}

package com.fengzhuang;
public class Test{

public static void main(String[] args){
    Car b=new Car();//实例化操作
    b.setName("宝马");//赋值
    b.setColor("红色");
    b.setSize("大型");
    //很明显这些过程看不到如何实现。
    String name=b.getName();//取值
    String color=b.getColor();
    String size=b.getSize();
    //最后输出结果
    System.out.println(name+":"+color+":"+size);
}

}

输出:
宝马:红色:大型

解析:因为声名变量的时候我们已经设置他们几个为私有变量了,所以我们要是还想在访问它的话只有通过set这个建立器才可以进行访问

4.个人心得总结
前面已经说了这么写了,那我就最后说一点,总结一下这些吧!

封装的优势在于定义只可以在类内部进行对属性的操作,外部无法对这些属性指手画脚,要想修改,也只能通过你定义的封装方法;
继承减少了代码的冗余,省略了很多重复代码,开发者可以从父类底层定义所有子类必须有的属性和方法,以达到耦合的目的;
多态实现了方法的个性化,不同的子类根据具体状况可以实现不同的方法,光有父类定义的方法不够灵活,遇见特殊状况就捉襟见肘了
这些是我对这些的理解,希望可以对大家有所帮助。——总而言之,这块真的是非常重要的,就是java语言的跟呀!大家一定要好好的理解,多琢磨琢磨,多写写代码,多思考,自然就不难了,就好比"会了不难,难了不会"这个道理是一样的,写这篇文章一方面是为了记录一下子知识点,另一方面也是希望可以帮助那些对这些概念,和代码的运用一知半解的朋友们,原创这篇文章真的很不容易写了好久,希望大家可以多多支持,要是有不懂的可以私信我或者在地下评论,看到了之后我会尽我所能为大家解答的,大家一起学习。(另外明后天我还会陆续连载一些原创文章的要是觉得我写的对你们有帮助的话,可以关注我一下子,方便查找 )

原文地址https://www.cnblogs.com/xiao666/p/12815077.html

相关文章
|
8天前
|
存储 Java 开发者
什么是java的Compact Strings特性,什么情况下使用
Java 9引入了紧凑字符串特性,优化了字符串的内存使用。它通过将字符串从UTF-16字符数组改为字节数组存储,根据内容选择更节省内存的编码方式,通常能节省10%至15%的内存。
|
17天前
|
存储 Java 数据挖掘
Java 8 新特性之 Stream API:函数式编程风格的数据处理范式
Java 8 引入的 Stream API 提供了一种新的数据处理方式,支持函数式编程风格,能够高效、简洁地处理集合数据,实现过滤、映射、聚合等操作。
34 6
|
24天前
|
Java
在Java中,接口之间可以继承吗?
接口继承是一种重要的机制,它允许一个接口从另一个或多个接口继承方法和常量。
69 1
|
1月前
|
分布式计算 Java API
Java 8引入了流处理和函数式编程两大新特性
Java 8引入了流处理和函数式编程两大新特性。流处理提供了一种声明式的数据处理方式,使代码更简洁易读;函数式编程通过Lambda表达式和函数式接口,简化了代码书写,提高了灵活性。此外,Java 8还引入了Optional类、新的日期时间API等,进一步增强了编程能力。这些新特性使开发者能够编写更高效、更清晰的代码。
33 4
|
2月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
26 3
|
2月前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
46 2
|
2月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
35 2
|
2月前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
94 3
|
2月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
41 1
Java基础-抽象队列同步器:AbstractQueuedSynchronizer(1)
AQS定义了一套多线程访问共享资源的同步器框架。 许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch。 它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列。 多线程争用资源被阻塞时会进入此队列。 AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。
131 0