爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      Java面向对象(下)

      首页 知识中心 软件开发 文章详情页

      Java面向对象(下)

      2023-08-03 07:23:47 阅读次数:429

      java,对象

      Java面向对象(下)

      本文介绍Java的继承( Inheritance])、封装(Encapsulation)、多态(Polymorphism)。

      封装

      封装把一个对象的部分成员变量私有化,隐藏类的细节,同时提供--些可以被外界访问的成员变量的方法,如果成员变量不想被外界访问,我们大可不必提供方法给外界访问。

      封装的目的是:增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员。

      封装的基本要求是:把所有的成员变量私有化,对每个成员变量提供getter和setter方法,如果有一个带参的构造函数的话,那一定要写一个不带参的构造函数。在开发的时候经常要对已经编写的类进行测试,所以在有的时候还有重写toString方法,但这不是必须的。

      继承

      继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。被继承的类称为“基类”、“父类”或“超类”;通过继承创建的新类称为“子类”或“派生类”。

        构造方法、私有成员变量和方法、静态成员变量和方法不能被继承。

        1.子类拥有父类非private 的成员变量和方法。

        2.子类可以拥有自己成员变量和方法,即子类可以对父类进行扩展。

        3.子类可以用自己的方式实现父类的方法。

      多态

      所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。在Java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。

      Java实现多态有三个必要条件:

      继承:在多态中必须存在有继承关系的子类和父类。

      重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

      向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

      只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。

      多态的实现方式:

      (1)基于继承实现的多态

      基于继承的实现机制主要表现在父类和继承该父类的一个或多个子类对某些方法的重写,多个子类对同一方法的重写可以表现出不同的行为。

      (2)基于接口实现的多态

      继承是通过重写父类的同一方法的几个不同子类来体现的,那么就可就是通过实现接口并覆盖接口中同一方法的几不同的类体现的。

      在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。

      继承都是单继承,只能为一组相关的类提供一致的服务接口。但是接口可以是多继承多实现,它能够利用一组相关或者不相关的接口进行组合与扩充,

      能够对外提供一致的服务接口。所以它相对于继承来说有更好的灵活性。

       

      Jave类的继承和多态思维导图

      Java面向对象(下)

       

      封装

      简单地说,Java的封装就是在设计类时用好访问修饰符(public、protected、private)控制方法、属性等成员的访问权限。

      在设计类时,我们需要根据需求合理地使用这些访问修饰符,将类的一些成员标记为private,即私有成员,以控制其访问权限,防止外部对象直接访问,从而保证数据的安全性。同时,类也可以提供公开的方法(例如getter和setter方法),以供外部对象访问和修改私有成员,从而实现对外暴露必要的接口。这里的“接口”【注】指的是类对外暴露的方法和属性,包括公共方法和属性等。

      【注:接口(interface)有多种含义
      1.在编程中,将类对外暴露的公共方法和属性等成员称为接口(interface),目的是使其能被内部修改而不影响外界其他实体与其交互沟通的方式;
      2.在编程中,只包含方法声明但没有具体实现的接口,需要使用关键字"interface"来定义;
      3.计算机网络中,用于描述不同系统之间的连接点或共享的边界,例如网络接口、API接口等。】
       

      封装的特点:

      只能通过规定的方法访问数据。

      隐藏类的实例细节,方便修改和实现。

      Java封装类实现途径:

      (1)修改成员变量的可见性来限制对成员变量的访问,一般设为 private。

      (2)为每个成员变量创建一对赋值和取值 (setter  & getter)方法,一般设为 public,用于成员变量的读写。

      (3)在赋值和取值方法中,加入成员变量控制语句(对成员变量值的合法性进行判断)。如在读取成员变量的方法中,添加对成员变量读取的限制。

      在此需要请回顾一下,Java 支持访问权限修饰符有4 种:default (即默认,什么也不写)、private 、public、protected。在前文中已介绍,在此不多说了。

       

      下面给出一个简单示例。封装之前:成员变量都可以直接访问和修改

      class Person{

        String name;

        int age;

      }

      在此例中,其成员的访问权限修饰符是default (即缺省、默认,什么也不写),因此,其成员变量都可以直接访问和修改。

       

      封装之后:

      class Person{

        //成员变量私有化,使得其他对象不能直接访问

        private String name;

        private int age;

        //参数及方法内定义的变量是局部变量

        public void setName(String name){

        this.name = name;}

        public String getName(){

        return name;}

      }

       

      示例

      下面示例,以一个员工类的封装为例介绍封装过程。包括两个文件:员工mployee.java文件和测试用EmployeeTest.java文件

      Employee.java文件包含员工类Employee主要成员变量有姓名、年龄、联系电话和家庭住址。代码如下:

      //Employee类

      public class Employee {

          private String name; // 姓名

          private int age; // 年龄

          private String phone; // 联系电话

          private String address; // 家庭住址

       

          public String getName() {

              return name;

          }

       

          public void setName(String name) {

              this.name = name;

          }

       

          public int getAge() {

              return age;

          }

       

          public void setAge(int age) {

              // 对年龄进行限制

              if (age < 18 || age > 40) {

                  System.out.println("年龄必须在18到40之间!");

                  this.age = 20; // 默认年龄

              } else {

                  this.age = age;

              }

          }

       

          public String getPhone() {

              return phone;

          }

       

          public void setPhone(String phone) {

              this.phone = phone;

          }

       

          public String getAddress() {

              return address;

          }

       

          public void setAddress(String address) {

              this.address = address;

          }

      }

      其中,如代码所示,使用 private 关键字修饰成员变量,这就意味着除了 Employee 类本身外,其他任何类都不可以访问这些成员变量。但是,可以通过这些成员变量的 setXxx() 方法来对其进行赋值,通过 getXxx() 方法来访问这些成员变量。

      其中 setAge() 方法,首先对用户传递过来的参数 age 进行判断,如果 age 的值不在 18 到 40 之间,则将 Employee 类的 age 成员变量值设置为 20,否则为传递过来的参数值。

       

      EmployeeTest.java文件包含测试类 EmployeeTest,代码如下:

      //EmployeeTest类

      public class EmployeeTest {

          public static void main(String args[]){

              Employee people = new Employee();

              people.setName("李明");

              people.setAge(35);

              people.setPhone("13612345678");

              people.setAddress("某某省某某市");

             

              System.out.println("姓名:" + people.getName());

              System.out.println("年龄:" + people.getAge());

              System.out.println("电话:" + people.getPhone());

              System.out.println("家庭住址:" + people.getAddress());

          }

      }

      在该类的 main() 方法中调用 Employee 类的setXxx() 方法对其相应的成员变量进行赋值,并调用 getXxx() 方法访问成员变量。

      运行该示例,输出结果如下:

      姓名:李明

      年龄:35

      电话:13612345678

      家庭住址:某某省某某市

       

      继承

      继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

      在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,类的继承格式:

      class 父类名称 {

      }

      class 子类名称 extends 父类名称 {

      }

      父类名称也称为基类名称,Java 的继承通过 extends 关键字来实现。

      【Java 与 C++ 定义继承类的方式十分相似。Java 用关键字 extends 代替了 C++ 中的冒号(:)。在 Java 中,所有的继承都是公有继承, 而没有 C++ 中的私有继承和保护继承。】

      类的继承不改变类成员的访问权限,也就是说,如果父类的成员是公有的、被保护的或默认的,它的子类仍具有相应的这些特性,并且子类不能获得父类的构造方法。

      使用继承的注意:子类一般比父类包含更多的成员变量和方法;父类中的 private 成员在子类中是不可见的,因此在子类中不能直接使用它们。

      继承可以理解为一个类从另一个类获取方法和成员变量的过程。如果类B继承于类A,那么B就拥有A的方法和成员变量。

      在Java中,父类和继承父类的子类可以保存在同一个文件中,也可以分别保存成不同的文件。

      通常情况下,我们建议将每个类保存到单独的文件中,这样可以使代码更易于阅读和维护。具体来说,我们会将父类定义到一个文件中,并且将其所有的子类都定义到另外的文件中。

      但是,在小型的应用程序中,将多个类定义在同一个文件中可能会更加方便,因为它可以减少文件数量,使代码更具有紧凑性。所以,根据需要和实际情况,可以灵活选择是否将父类和子类保存到同一个文件中。

      当你在同一个源文件中定义一个父类和其继承子类时,需要注意以下几点:

      父类必须先于其子类进行定义;

      子类的定义需要使用关键字"extends"来指明其继承自哪个父类;

      如果父类和子类都是public类,则源文件的名称必须与父类的名称相同。

       

      假设我们已经定义了一个类 People:

      class People{

          String name;

          int age;

          int height;

        

          void say(){

              System.out.println("我的名字是 " + name + ",年龄是 " + age + ",身高是 " + height);

          }

      }

       

      现在需要定义一个类 Teacher,它也有 name、age、height 成员变量和 say() 方法,另外还需要增加 school、seniority、subject 成员变量和 lecturing() 方法,怎么办呢?我们要重新定义一个类吗?

      完全没必要,可以先继承 People 类的成员,再增加自己的成员即可,例如:

      class Teacher extends People{

          String school;  // 所在学校

          String subject;  // 学科

          int seniority;  // 教龄

        

          // 覆盖 People 类中的 say() 方法

          void say(){

              System.out.println("我叫" + name + ",在" + school + "教" + subject + ",有" + seniority + "年教龄");

          }

        

          void lecturing(){

              System.out.println("我已经" + age + "岁了,依然站在讲台上讲课");

          }

      }

      说明

      name 和 age 变量虽然没有在 Teacher 中定义,但是已在 People 中定义,可以直接拿来用。

      Teacher 是 People 的子类,People 是Teacher 类的父类。

      子类可以覆盖父类的方法。

      子类可以继承父类除private以为的所有的成员。

      构造方法不能被继承。

       

      对上面的代码进行整理为完整的代码如下:

      public class DemoA {

          public static void main(String[] args) {

              Teacher t = new Teacher();

              t.name = "汤姆";

              t.age = 60;

              t.school = "某某学校";

              t.subject = "Java程序设计";

              t.seniority = 12;

              t.say();

              t.lecturing();

          }

      }

       

      class People{

          String name;

          int age;

          int height;

        

          void say(){

              System.out.println("我的名字是 " + name + ",年龄是 " + age + ",身高是 " + height);

          }

      }

       

      class Teacher extends People{

          String school;  // 所在学校

          String subject;  // 学科

          int seniority;  // 教龄

        

          // 覆盖 People 类中的 say() 方法

          void say(){

              System.out.println("我叫" + name + ",在" + school + "教" + subject + ",有" + seniority + "年教龄");

          }

        

          void lecturing(){

              System.out.println("我已经" + age + "岁了,依然站在讲台上讲课");

          }

      }

      运行结果如下:

      我叫汤姆,在某某学校教Java程序设计,有12年教龄

      我已经60岁了,依然站在讲台上讲课

       

      Java类的单继承性:Java 允许一个类仅能继承一个其它类,即一个类只能有一个父类,这个限制被称做单继承性。但接口(interface)允许多继承。

       

      一个类只能有一个直接父类,但是它可以有多个间接的父类。例如:

      Java面向对象(下)

      从图 1 中可以看出,三角形、四边形和五边形的直接父类是多边形类,它们的间接父类是图形类。图形类、多边形类和三角形、四边形、五边形类形成了一个继承的分支。在这个分支上,位于下层的子类会继承上层所有直接或间接父类的成员变量和方法。如果两个类不在同一个继承树分支上,就不会存在继承关系,例如多边形类和直线。

       

      如果定义一个 Java 类时并未显式指定这个类的直接父类,则这个类默认继承 java.lang.Object 类。因此,java.lang.Object 类是所有类的父类,要么是其直接父类,要么是其间接父类。因此所有的 Java 对象都可调用 java.lang.Object 类所定义的实例方法。

       

      在继承中需要注意的几种情况:

      ☆Java成员变量的隐藏(成员变量的覆盖)

      当子类中声明的成员变量名字和从父类继承过来的成员变量名字相同时,子类就会使用自己声明的成员变量,隐藏从父类继承过来的成员变量。

      Java成员变量的隐藏特点:

      1)子类对象和子类自己定义的方法,在操作与父类同名的成员变量时,使用的是子类声明的成员变量,而不是父类的。例如:

      本例有两个类文件:父文件variableHidden.java代码如下:

      //父类

      public class variableHidden {

             //父类成员变量

             double number = 456.456 ;

      }

       

      子类文件variableHidden_Test.java代码如下:

      //子类

      public class variableHidden_Test extends variableHidden{

              double number = 11.11;

              //方法中操作 number 成员变量,此时使用的number是子类自己声明的number

              void Operation(int x){

              number += x;

              System.out.println("成员变量number的值:"+number);

              }

              

              public static void main(String[] args) {

                     //子类对象操作成员变量number

                     variableHidden_Test vht = new variableHidden_Test();

                     vht.number = 111.111;

                     System.out.println("子类对象操作成员变量number的值:"+vht.number);

                     //子类对象操作方法

                     vht.Operation(100);

             }

      }

       

      输出如下:

      子类对象操作成员变量number的值:111.111

      成员变量number的值:211.111

       

      2)子类继承父类的方法中,所操作的成员变量一定是被子类继承或隐藏的成员变量,而不是子类自己声明的成员变量。例如:

      本例有两个类文件:父文件variableHidden.java代码如下:

      定义两个类文件:父文件variableHidden2.java代码如下:

      //父类

      public class variableHidden2 {

              //父类成员变量

              double number = 456.456 ;

              //父类的方法,方法中操作自己的成员变量

              void Fa(){

                       System.out.println("父类方法,操作自己的成员变量number:"+number);

              }

      }

       

      子类文件variableHidden_Test2.java代码如下:

      //子类

      public class variableHidden_Test2 extends variableHidden2{

              //对父类的成员变量进行隐藏

              double number = 11.11;

              //方法中操作 number 成员变量

              void Operation(int x){

                      number += x;

                      System.out.println("成员变量number的值:"+number);

              }

              public static void main(String[] args) {

                      //子类对象操作成员变量number

                      variableHidden_Test2 vht = new variableHidden_Test2();

                      vht.number = 111.111;

                      System.out.println("子类对象操作成员变量number的值:"+vht.number);

                      //子类对象操作自己的方法

                      vht.Operation(100);

                      //子类对象操作父类的方法,方法中操作的是父类的成员变量

                      vht.Fa();

              }

      }

       

      输出如下:

      子类对象操作成员变量number的值:111.111

      成员变量number的值:211.111

      父类方法,操作自己的成员变量number:456.456

       

      ☆Java方法的重写(方法的覆盖)和方法的重载

      方法的重写和重载是体现继承特性的重要方面,理解了方法的重写和重载,可以为以后学习多态打下基础。在子类本身的方法中,如果有和所继承的方法具有相同的名称,便构成了方法的重写。重写的特点就是能够为各个子类定义所特有的行为。方法的重载就是指在一个类中,存在两个或者两个以上的具有相同名称,不同参数的方法。这样做就可以让程序员不必为同一个操作的不同变体而设置多个不同的方法名称。

       

      先介绍方法的重写

      Java方法重写:

      1、子类通过重写可以隐藏从父类继承过来的方法,方法重写(override)也称为方法覆盖。

      2、子类一旦重写了父类的方法,那父类被重写的方法就会被隐藏;子类通过方法的重写可以把父类的状态和行为改变为自身的状态和行为。

      3、子类在重写父类的方法时,不允许降低方法的访问权限,但可以提高方法的访问权限。

      方法重写的语法规则:

      1、子类中定义一个方法,这个方法的类型和父类的方法的类型是一致的,

      2、而且方法的名字,参数个数,参数类型也要和父类的方法一致;

      3、只有方法体是可以不一致的;

      例如

      定义两个类文件:父文件methodRewrite.java代码如下:

      //父类methodRewrite

      public class methodRewrite {

              //定义一个父类方法

              void Method(int x,int y){

                      int sum = x * y ;

                      System.out.println("我是父类的方法,输出x * y = "+sum);

              }

      }

       

      子类文件子文件methodRewrite_Test.java代码如下:

      //子类methodRewrite_Test

      public class methodRewrite_Test extends methodRewrite {

              //对继承的父类方法进行重写

              void Method(int x,int y){

                      System.out.println("我重写了父类的Method方法");

              }

              public static void main(String[] args) {

                      methodRewrite_Test mrt = new methodRewrite_Test();

                      mrt.Method(11,111);

              }

      }

       

      输出如下:

      我重写了父类的Method方法

       

      super关键字

      重写方法时既可以操作继承的成员变量,调用继承的方法,也可以操作子类新声明的成员变量,调用新定义的其他方法,但无法使用被子类隐藏的成员变量和方法;当子类想要使用被隐藏的方法或成员变量时,怎么办?必须使用关键字 super。

      例如,定义两个类文件:父文件methodRewrite2.java代码如下:

      //父类methodRewrite2

      public class methodRewrite2{

              //创建父类成员变量 和 方法

              int numberFa = 11;

              void methodFa(int x,int y){

                      int sum = x+y;

                      System.out.println("我是父类的方法,计算 x+y ="+sum);

              }

       

              //被子类重写方法

              void Fa(int x,int y,int z){

                      int muti = x*y*z;

                      System.out.println("我是父类的方法,计算 x*y*z ="+muti);

              }

       

              //被子类隐藏的成员变量

              int Fs = 100 ;

      }

      子文件methodRewrite_Test2.java代码如下:

      //子类methodRewrite_Test2

      public class methodRewrite_Test2 extends methodRewrite2{

              //子类新声明的成员变量和方法

              int numberCh = 111 ;

              void methodCh(double x,double y){

                      double div = x/y;

                      System.out.println("我是子类的方法,计算 x/y ="+div);

              }

              //隐藏父类的成员变量Fs

              int Fs = 159 ;

                 

              //方法重写,在方法中操作继承的成员变量,调用继承的方法,操作自己新声明的成员变量和方法

              void Fa(int x,int y,int z){

                      //操作继承的成员变量,调用继承的方法

                      numberFa = 789;

                      System.out.println("numberFa= "+numberFa);

                      methodFa(111,111);

                      //操作自己新声明的成员变量和方法

                      numberCh = 456 ;

                      System.out.println("numberCh= "+numberCh);

                      methodCh(888,222);

                      //但无法使用被子类隐藏的成员变量和方法;

                      Fs = 77 ;  //此时的Fs是子类自己声明的成员变量,而父类的成员变量Fs已经被隐藏了

                      System.out.println("Fs= "+Fs);

                      //使用关键字 super 调用被子类隐藏的成员变量

                      System.out.println("super.Fs= "+super.Fs);

                   

                      int sub = x-y-z;

                      System.out.println("我重写了父类的方法,计算 x-y-z ="+sub);

              }

            

              public static void main(String[] args) {

                      //子类对象

                      methodRewrite_Test2 mrt = new methodRewrite_Test2();

                      //调用继承父类的成员变量和方法;

                      System.out.println("我调用了父类的成员变量numberFa:"+mrt.numberFa);

                      mrt.methodFa(123,1234);

                          

                      //调用子类自己的成员变量和方法;

                      System.out.println("子类自己的成员变量numberCh:"+mrt.numberCh);

                      mrt.methodCh(100,2);

                   

                      //调用子类重写的方法

                      mrt.Fa(100,10,10);

              }

      }

       

      输出如下:

      我调用了父类的成员变量numberFa:11

      我是父类的方法,计算 x+y =1357

      子类自己的成员变量numberCh:111

      我是子类的方法,计算 x/y =50.0

      numberFa= 789

      我是父类的方法,计算 x+y =222

      numberCh= 456

      我是子类的方法,计算 x/y =4.0

      Fs= 77

      super.Fs= 100

      我重写了父类的方法,计算 x-y-z =80

       

      super 关键字的功能:

      1)访问父类的成员方法和变量。种情况见前例。

      2)在子类的构造方法中显式的调用父类构造方法。

      下面介绍使用super调用父类构造方法

      super 关键字可以在子类的构造方法中显式地调用父类的构造方法,基本格式如下:

      super(parameter-list);

      其中,parameter-list 指定了父类构造方法中的所有参数。super( ) 必须是在子类构造方法的方法体的第一行。如:

      public  class apple extends fruits

      {

          public apple(int price)

          {

              super(price);

              super.var = value;

              super.method(paraList);

          }

      }

       

      下面给出一个比较完整的例子,包含两个类文件:父文件superKeyword.java代码如下:

       //父类superKeyword

       public class superKeyword {

               //父类的成员变量

              int numberFa;

              //无参数构造方法

              superKeyword(){

                      System.out.println("系统默认调用了父类无参数构造方法 ");

              }

              superKeyword(int numberFa){

                      this.numberFa = numberFa;

                      System.out.println("父类的手机号码: "+numberFa);

              }

      }

       

      子类文件子文件superKeyword_Test .java代码如下:

      //子类superKeyword_Test

      public class superKeyword_Test extends superKeyword {

              //成员变量

              int age,number;

              double Fraction;

       

              //没有super();的情况时,系统默认该方法有 super(),此时就调用了父类没有参数的构造方法

              superKeyword_Test(int age,int number){

                      this.age = age;

                      this.number = number;

                      System.out.println("子类的年龄:"+age+" 子类的手机号码: "+number+"\n");

              }

       

              //有super();的情况时,系统就调用父类相应参数的构造方法

              superKeyword_Test(double Fraction, int number) {

                      super(117330111);

                      this.Fraction = Fraction;

                      this.number = number;

                      System.out.println("子类的分数:"+Fraction+" 子类的手机号码: "+number);

              }

       

              public static void main(String[] args){

                      //调用没有super()的构造方法

                      superKeyword_Test skt = new superKeyword_Test(18,117120); 

                      //调用有super()的构造方法

                      superKeyword_Test skt1 = new superKeyword_Test(111.11,117110);    

              }

      }

       

      输出结果:

      系统默认调用了父类无参数构造方法

      子类的年龄:18 子类的手机号码: 117120

       

      父类的手机号码: 117330111

      子类的分数:111.11 子类的手机号码: 117110

       

      super 关键字的用法小结如下:

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

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

      super():调用父类的无参构造方法

      super(参数):调用父类的有参构造方法。

      在重写方法时,需要遵循下面的规则:

      ☆参数列表必须完全与被重写的方法参数列表相同。

      ☆返回的类型必须与被重写的方法的返回类型相同(Java1.5 版本之前返回值类型必须一样,之后的 Java 版本放宽了限制,返回值类型必须小于或者等于父类方法的返回值类型)。

      ☆访问权限不能比父类中被重写方法的访问权限更低(public>protected>default>private)。

      ☆重写方法一定不能抛出新的检査异常或者比被重写方法声明更加宽泛的检査型异常。例如,父类的一个方法声明了一个检査异常 IOException,在重写这个方法时就不能抛出 Exception,只能拋出 IOException 的子类异常,可以抛出非检査异常。

      ☆父类的成员方法只能被它的子类重写。

      ☆声明为 final 的方法不能被重写。

      ☆声明为 static 的方法不能被重写,但是能够再次声明。静态方法就是被修饰为了static类型的方法,在类里声明具有唯一性,不是通过类的实例化而存在的,而是通过类的建立而存在,可以理解为用关键字new创建对象了,就是把这个对象实例化了。Java中的静态方法可以被继承,但是不可以被重写。

      ☆构造方法不能被重写。

      ☆子类和父类在同一个包中时,子类可以重写父类的所有方法,除了声明为 private 和 final 的方法。

      ☆子类和父类不在同一个包中时,子类只能重写父类的声明为 public 和 protected 的非 final 方法。

      ☆如果不能继承一个方法,则不能重写这个方法。

      ☆另外,重写的方法可以使用 @Override 注解来标识。

       

      方法的重载

      方法重载(overload)指一个类中可以有多个方法具有相同的名字,但是这些方法的参数必须不同;参数不同指:

      (1)、参数的个数不同 ;

      (2)、参数个数相同,但是对于的某个参数的类型不同 ;

      例如:

      void test ( int x ){ }

      void test ( int x,int y ){ }

      void test (double x,int y ){ }

      方法重载的要求是两同一不同:同一个类中方法名相同,参数列表不同。至于方法的其他部分,如方法返回值类型、修饰符等,与方法重载没有任何关系。

      使用方法重载其实就是避免出现繁多的方法名,有些方法的功能是相似的,如果重新建立一个方法,重新取个方法名称,会降低程序可读性。

      例如:

      在比较数值时,数值的个数和类型是不固定的,可能是两个 int 类型的数值,也可能是两个 double 类型的数值,或者是两个 double、一个 int 类型的数值;在这种情况下就可以使用方法的重载来实现数值之间的比较功能。代码如下:

      public class OverLoading {

          public void max(int a, int b) {

              // 含有两个int类型参数的方法

              System.out.println(a > b ? a : b);

          }

       

          public void max(double a, double b) {

              // 含有两个double类型参数的方法

              System.out.println(a > b ? a : b);

          }

       

          public void max(double a, double b, int c) {

              // 含有两个double类型参数和一个int类型参数的方法

              double max = (double) (a > b ? a : b);

              System.out.println(c > max ? c : max);

          }

       

          public static void main(String[] args) {

              OverLoading ol = new OverLoading();

              System.out.println("1 与 5 比较,较大的是:");

              ol.max(1, 5);

              System.out.println("5.205 与 5.8 比较,较大的是:");

              ol.max(5.205, 5.8);

              System.out.println("2.15、0.05、58 中,较大的是:");

              ol.max(2.15, 0.05, 58);

          }

      }

      虽然 3 个 max() 方法的方法名相同,但因为它们的形参列表不同,所以系统可以正常区分出这 3 个方法。当运行时,Java 虚拟机会根据传递过来的不同参数来调用不同的方法。运行结果如下:

      1 与 5 比较,较大的是:

      5

      5.205 与 5.8 比较,较大的是:

      5.8

      2.15、0.05、58 中,较大的是:

      58.0

       

      final关键字

      final关键字有最终、不变的意思,可以修饰成员变量,也可以修饰方法和类,而且会对类的继承产生很大的影响。通过final关键字的修饰可以改变其特性。

      有三种使用方法

      final在类之前,表示该类不能被继承。

      final在方法之前,防止该方法被覆盖。

      final在变量之前,定义一个常量。

      通过extends关键字可以实现类的继承。但在实际应用中,出于某种考虑,当创建一个类时,希望该类永不需要做任何变动,或者出于安全因素,不希望它有任何子类,这时可以使用final关键字。在类的定义时,使用final修饰符,意味着这个类不能再作为父类派生出其他的子类,这样的类通常称为最终类。

      如:

      用final修饰符定义的常量不能修改

      例、

      public class  ConstantTest{       

           public static void main(String[] args){

               final int i1 = 10; 

               //下句提示出错

               i1=i1+1;

               System.out.println(i1);

               int i2 = 10; 

               //下句可以

               i2=i2+1;

               System.out.println(i2);

           }

      }

       

      用final修饰符定义最终方法,该方法不能被覆盖

      class A{

             final void a(){

             ……

             }            

      ……

      }

       

      用final修饰的类,该类不能被继承。

       

      abstract关键字

      abstract关键字是表示抽象的意思。

      在Java里,抽象类不能被实例化;抽象类里最少要含有一个抽象方法,让它的子类去实现这个抽象方法,抽象类里也可以定义一些方法。

      下例父类Bike被修饰为abstract,因此它是一个抽象类,其子类RacingCycleA可以实现抽象类的抽象方法。

      //bike类所描述的是一个自行车,被申明为abstract抽象的
      abstract class bike 
      {
          public String name = "抽象类的成员变量";
          
          public String getMessage()
          {
              //返回bile类里的成员变量name的值
              return name;
          }
          
          //注意这个public类型的方法getMes(),被修饰为了abstract
          abstract public String getMes();
      }

      //racing_cycle类所描述的是公路赛车,继承与bike类,bike类是抽象了,并实现了相应的抽象方法
      public class racingCycleA extends bike
      {
          //实现了父类bike的抽象方法getMes()
          public String getMes()
          {
              return getMessage();
          }

          public static void main(String args[])
          {
              racingCycleA rc = new racingCycleA();
              //打印并显示运行结果
              System.out.println(rc.getMes());
          }
      }
       

      运行输出结果是:

      抽象类的成员变量

       

      多态

      多态性是面向对象编程的一个重要特征,它是指在父类中定义的成员变量和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个成员变量或方法在父类及其各个子类中具有不同的含义。

      对面向对象来说,多态分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是大家通常所说的多态性。

      Java 实现多态有 3 个必要条件:继承、重写和向上转型。只有满足这 3 个条件,开发人员才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而执行不同的行为。

      继承:在多态中必须存在有继承关系的子类和父类。

      重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

      向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才既能可以调用父类的方法,又能调用子类的方法。

      下面通过一个例子来演示重写如何实现多态性。

      1)创建 Figure 类,在该类中首先定义存储二维对象的尺寸,然后定义有两个参数的构造方法,最后添加 area() 方法,该方法计算对象的面积。代码如下:

      // Figure类

      public class Figure {

          double dim1;

          double dim2;

          Figure(double d1, double d2) {

              // 有参的构造方法

              this.dim1 = d1;

              this.dim2 = d2;

          }

          double area() {

              // 用于计算对象的面积

              System.out.println("父类中计算对象面积的方法,没有实际意义,需要在子类中重写。");

              return 0;

          }

      }

       

      2)创建继承自 Figure 类的 Rectangle 子类,该类调用父类的构造方法,并且重写父类中的 area() 方法。代码如下:

      // Rectangle子类

      public class Rectangle extends Figure {

          Rectangle(double d1, double d2) {

              super(d1, d2);

          }

          double area() {

              System.out.println("长方形的面积:");

              return super.dim1 * super.dim2;

          }

      }

       

      3)创建继承自 Figure 类的 Triangle 子类,该类与 Rectangle 相似。代码如下:

      // Triangle子类

      public class Triangle extends Figure {

          Triangle(double d1, double d2) {

              super(d1, d2);

          }

          double area() {

              System.out.println("三角形的面积:");

              return super.dim1 * super.dim2 / 2;

          }

      }

       

      4)创建 RunTest 运行测试类,在该类的 main() 方法中首先声明 Figure 类的变量 figure,然后分别为 figure 变量指定不同的对象,并调用这些对象的 area() 方法。代码如下:

      //RunTest运行测试类

      public class RunTest {

          public static void main(String[] args) {

              Figure figure; // 声明Figure类的变量

              figure = new Rectangle(9, 9);

              System.out.println(figure.area());

              System.out.println("===============================");

              figure = new Triangle(6, 8);

              System.out.println(figure.area());

              System.out.println("===============================");

              figure = new Figure(10, 10);

              System.out.println(figure.area());

          }

      }

      从上述代码可以发现,无论 figure 变量的对象是 Rectangle 还是 Triangle,它们都是 Figure 类的子类,因此可以向上转型为该类,从而实现多态。输出结果如下:

      长方形的面积:

      81.0

      ===============================

      三角形的面积:

      24.0

      ===============================

      父类中计算对象面积的方法,没有实际意义,需要在子类中重写。

      0.0

       

      面向对象设计的几个基本原则

      这些原则是在许多设计中总结出的指导性原则,并不是任何设计都必须要遵守的硬性规定。

      ☆在设计模式中,使用简单的 UML类图可以简洁地表达一个模式中类之间的关系。

      ☆面向抽象原则的核心思想是:在设计一个类时,不让该类面向具体的类,而是面向抽象类或接口

      ☆开-闭原则的本质是指当一个设计中增加新的模块时,不需要修改现有的模块。

      ☆“多用组合、少用继承”原则的目的是减少类之间的强耦合关系。

      ☆“高内聚-低耦合”原则的目的是尽量不要让一个类含有太多的其他类的实例的引用,便于类的维护。

      关于这些,在此仅提及,想深入了解请参考其他文献。

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/cnds123/article/details/111224225,作者:软件开发技术爱好者,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:JavaScript流程控制语句

      下一篇:JavaScript的按钮方法报错:1 argument required, but only 0 present.

      相关文章

      2025-05-19 09:04:44

      js小题2:构造函数介绍与普通函数对比

      js小题2:构造函数介绍与普通函数对比

      2025-05-19 09:04:44
      new , 关键字 , 函数 , 对象 , 构造函数
      2025-05-19 09:04:22

      外设驱动库开发笔记54:外设库驱动设计改进的思考

      外设驱动库开发笔记54:外设库驱动设计改进的思考

      2025-05-19 09:04:22
      使用 , 函数 , 初始化 , 定义 , 对象
      2025-05-19 09:04:22

      外设驱动库开发笔记46:MAX31855热偶变送器驱动

      外设驱动库开发笔记46:MAX31855热偶变送器驱动

      2025-05-19 09:04:22
      对象 , 温度
      2025-05-16 09:15:24

      jQuery遍历对象、数组、集合

      jQuery遍历对象、数组、集合

      2025-05-16 09:15:24
      jQuery , 对象 , 数组 , 遍历 , 集合
      2025-05-14 10:33:31

      计算机初级选手的成长历程——操作符详解(2)

      计算机初级选手的成长历程——操作符详解(2)

      2025-05-14 10:33:31
      对象 , 操作 , 操作符 , 表达式 , 运算 , 逗号 , 逻辑
      2025-05-14 10:33:16

      30天拿下Python之使用Json

      Json的英文全称为JavaScript Object Notation,中文为JavaScript对象表示法,是一种存储和交换文本信息的语法,类似XML。Json作为轻量级的文本数据交换格式,比XML更小、更快,更易解析,也更易于阅读和编写。

      2025-05-14 10:33:16
      json , Json , Python , 字符串 , 对象 , 序列化 , 转换
      2025-05-14 10:03:05

      C++ 11新特性之bind

      std::bind是C++ 11中<functional>头文件提供的一个函数模板,它允许我们将函数或成员函数与其部分参数预先绑定在一起,形成一个新的可调用对象(英文为:Callable Object)。

      2025-05-14 10:03:05
      bind , std , 函数 , 参数 , 对象 , 绑定 , 调用
      2025-05-14 10:03:05

      C++ 11新特性之右值引用

      C++ 11中引入了一项关键特性——右值引用,极大地增强了C++在资源管理、性能优化和表达力方面的能力。通过理解并合理运用右值引用,我们可以编写出更高效、更简洁且不易出错的代码。

      2025-05-14 10:03:05
      右值 , 对象 , 常量 , 引用 , 构造函数 , 绑定
      2025-05-14 10:03:05

      C++ 11新特性之week_ptr

      在C++11 标准中,智能指针的引入极大地提升了内存管理的安全性和便利性。除了已经广为人知的shared_ptr和unique_ptr之外,还有一个重要但相对较少被单独提及的智能指针类型——std::weak_ptr。

      2025-05-14 10:03:05
      ptr , shared , 对象 , 引用 , 指向 , 计数
      2025-05-14 10:02:58

      C++ 11新特性之function

      C++ 11标准库引入了许多创新功能,其中之一便是std::function。作为函数对象容器,std::function允许开发者在编译时不知道具体类型的情况下,存储和传递任意可调用对象,极大地提升了代码的灵活性和可复用性。

      2025-05-14 10:02:58
      function , std , 一个 , 函数 , 对象 , 调用 , 赋值
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5266521

      查看更多

      最新文章

      外设驱动库开发笔记54:外设库驱动设计改进的思考

      2025-05-19 09:04:22

      外设驱动库开发笔记46:MAX31855热偶变送器驱动

      2025-05-19 09:04:22

      30天拿下Python之使用Json

      2025-05-14 10:33:16

      C++ 11新特性之右值引用

      2025-05-14 10:03:05

      C++ 11新特性之week_ptr

      2025-05-14 10:03:05

      C++ 11新特性之bind

      2025-05-14 10:03:05

      查看更多

      热门文章

      JAVA__接口的作用

      2023-04-18 14:14:13

      Java学习之算术运算符两只老虎

      2023-04-19 09:23:13

      排序算法Java版-归并排序算法

      2023-04-24 11:25:19

      JAVA多线程学习笔记

      2023-05-11 06:05:48

      try...catch...finally java

      2023-03-29 09:40:26

      Java:apache.poi读写Excel文件

      2023-02-22 06:40:54

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      23种设计模式之 【建造者模式】

      在 Linux 中优雅地启动与停止 Spring Boot 项目

      使用graalvm native-image 快速暴露jar 代码为native 共享库

      Java中重载和重写的区别

      Page Objects模式源码分析,看源码不用卖萌

      【java基础】ArrayList源码解析

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号