当前位置: 首页 > news >正文

Java面向对象及其三大特征

面向对象编程思想

面向对象,简单来说就是由动作的执行者变为动作的操控者。结合具体例子来说就是使用某个人或者工具所具有的功能而不用去管功能的具体实现方式。例如现实中的项目开发,老板想要实现某些功能,但是他自己不会这些技术,所以他就会让员工去做这些事情,通过借助别的拥有你想要实现某些功能的过程就可以理解为面向对象。面向对象是相对于面向过程的。

类与对象
接着来了解下什么是 类与对象,世界是由什么组成的?我们这样考虑,世界是由动物、植物等组成的,动物又分为哺乳动物和非哺乳动物,哺乳动物又分为老虎、狮子、大象... ...可以继续分类下去。通过这个例子我们对人类进行分析,人都会直立行走、会说话、有两个眼睛一个鼻子、会使用工具、会劳动、会创造工具等特征,这就是人区别于其他动物的原因,当某个事物符合了人所具有的所有特征,我们就说他是一个人,老虎、狮子、海豚等不具备”人类“的某些特征,所以它们不是人。但是要注意:类不是具体的事物,而是由个体组成的集合。这样的个体就叫做对象。

所以,类描述了一组有相同特性(属性)和相同行为(方法)的对象。

面向对象三大特征

面向对象有三大特征,即封装、继承和多态

<font color=red>封装</font>
封装,也就是隐藏,隐藏对象功能的实现细节和属性或者不需要用户知道的内容,只提供与外部联系的接口供用户使用。

封装的好处
1、减少代码的耦合性,使代码更加精简。

2、提高代码的复用性,不必再重复写功能相近的代码。

封装的具体实现就是将某一功能或属性抽离出来,独立写成单独的方法或类,对类及其属性和方法设置访问权限限定该功能或属性可以被特定的访问者访问,访问权限有public、protected、private和默认。

public:在任何类中都能访问,即使不在同一包中。

protected:只能在本包和子类中访问,即使子类不和父类在同一包中,也能访问到。

private:只能在本类中被访问,子类也访问不到。

默认:只能在同一个包中被访问到。

注意:类只能访问其他类的public和protected修饰的属性和方法,不能访问到private修饰的。

来看具体例子:

public class Person {
   private String name;
   private int age;
   private String id;

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public String getId() {
       return id;
   }

   public void setId(String id) {
       this.id = id;
   }
}

这个简单的例子把人属性封装了进去,外部只能调用相应的get和set方法来对属性进行操作。

<font color=red>继承</font>
假设在描述某些事物的时候我们会发现他们具有许多相同的地方,例如鸟类,每种鸟都有眼睛,嘴巴,都会吃东西等,这些相同的地方可以把他们抽取出来定义成一个鸟类,当需要描述多种鸟时就不用再重复定义这些共性,直接继承鸟类即可,不必再重新续写重复内容。

注意:Java的继承不是像C++一样,Java只存在单继承且智只能继承父类的非私有成员,使用extends ,在调用子类构造方法时会调用父类无参构造方法,若父类没有无参构造,注意为其添加无参构造方法。super()方法可调用父类方法或变量。继承提高了程序的复用性、扩展性,也是 多态特征的前提。

super和this的区别:

super(参数):调用父类的某一构造函数

super.方法:调用父类中的方法;

super.变量名:调用父类中的变量

this:代表当前对象名

this与super如果要在构造函数里使用则都必须在构造函数的第一行,所以不能同时存在与构造函数里。

因为static不包含对象,this和super代表对象,所以不能在static域中使用super和this。

接口和抽象类
接口:interface 接口名{方法1;方法2…},默认修饰符为 public ,不能用其他修饰符修饰接口。

抽象类:当多个类都存在相同方法名,但是其实现方式却不相同时可以将它们进行抽取,定义成一个类,只有方法名没有具体实现,abstract class 类名{ abstract void…方法名();}

注意:仅实现抽象类的部分功能的类还是抽象类。抽象类除了不能被实例化外和正常类没什么区别。

接口与抽象类的区别:接口可以被实现多个中间用逗号隔开,使用 implements 关键字实现接口,实现了接口类必须全部实现接口中的方法。如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;继承抽象类如果不实现所有的抽象方法,子类必须声明为抽象类。

java不支持多继承,但是可以实现多个接口,形如

class Main extends A implements B,C...{ }
稍微注意下,接口之间也可以继承,而且是可以多继承(了解一下就行了,基本不提这个)。

多态
多态是同一个行为具有多个不同表现形式或形态的能力。

多态存在的三个必要条件
继承
重写
父类引用指向子类对象

java的多态中涉及到向上转型和向下转型。

Father f = new Child();

上面的例子为向上转型,父类引用指向子类对象。

Father f = new Child();
Child c = (Child) f;

向下转型即当我们有一个父类对象时,我们想要实现子类中的某些方法功能时就需要向下转型,上面的例子为向下转型。

用一个具体的实例说明向上转型与向下转型

abstract class Animal{
   public abstract void eat();
   public abstract void sleep();
}

class Cat extends Animal{
   public void eat()
   {
       System.out.println("猫吃鱼");
   }

   public void sleep()
   {
       System.out.println("猫睡觉");
   }

   public void ability()
   {
       System.out.println("猫抓老鼠");
   }
}

class Dog extends Animal
{
   public void eat()
   {
       System.out.println("狗吃骨头");
   }

   public void sleep()
   {
       System.out.println("狗睡觉");
   }

   public void ability()
   {
       System.out.println("狗看家");
   }
}

public class DuoTai{
   public static void main(String[] args){
       Animal a = new Cat();//自动向上转型
       a.sleep(); //Animal 类中定义了此方法,而子类中也重写了此方法,调用的是子类中的sleep()方法
       a.eat();
//a.ability();  编译失败,因为 a是父类Animal类的引用,而Animal类中未定义此方法,所以会报错
       getAbility(a);
   }
   public static void getAbility(Animal a){
       if(a instanceof Cat) {
           Cat c = (Cat) a;//向下转型,使用instanceof关键字判断是否是指定类的对象
           c.ability();
       }
       if(a instanceof Dog){
           Dog d = (Dogs) a;
           d.ability();
       }
   }
}



/**

*  执行结果为:

*  猫睡觉

*  猫吃鱼

*  猫抓老鼠

*/

相关文章:

  • canvas 五子棋游戏
  • 12-dm-permissions.rules
  • 我的建站经历(一)
  • IDEA常用插件整理
  • 个推开发者服务进阶之路
  • 安卓用户当心啦 这个App可能会偷走你的比特币
  • SpringMvc环境搭建(配置文件)
  • 51信用卡 Android自动埋点实践
  • redis发布订阅Java代码实现
  • 批量截取pdf文件
  • 怎么把视频里的音乐提取出来
  • 【BZOJ3097】 Hash Killer I
  • 从微服务迁移到工作流的经验之谈
  • ElasticSearch之Windows下安装
  • springboot学习之授权Spring Security
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • css布局,左右固定中间自适应实现
  • Git的一些常用操作
  • JDK 6和JDK 7中的substring()方法
  • Mithril.js 入门介绍
  • Python socket服务器端、客户端传送信息
  • ReactNative开发常用的三方模块
  • spring学习第二天
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 复杂数据处理
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 面试遇到的一些题
  • 前端代码风格自动化系列(二)之Commitlint
  • 如何使用 JavaScript 解析 URL
  • 微信小程序实战练习(仿五洲到家微信版)
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • #HarmonyOS:基础语法
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (python)数据结构---字典
  • (Ruby)Ubuntu12.04安装Rails环境
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (黑马C++)L06 重载与继承
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (十三)Flask之特殊装饰器详解
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .net 8 发布了,试下微软最近强推的MAUI
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET Core 版本不支持的问题
  • .NET delegate 委托 、 Event 事件
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET关于 跳过SSL中遇到的问题
  • :“Failed to access IIS metabase”解决方法
  • @ResponseBody
  • @synthesize和@dynamic分别有什么作用?