Java面向对象三大特征的理解

Java面向对象三大特征的理解面向对象三大特征的理解初始理解封装继承多态初始理解其实这些知识很早就有接触,而且一些概念也牢记于心了。自己叙述面向对象的特征会是这样的:面向对象的三大特征是封装、继承和多态。封装是对代码的封装以实现迪内聚高耦合的设计,使代码更安全且具有良好的扩展性。继承是父类产生子类的过程,子类可以使用父类的非私有的属性和方法。多态是一个对象在不同时刻可以表现出不同状态的现象。外加Animal和Cat的例子。这一段时间敲了不少的Java代码,在敲代码的过程中想了无数次的面向对象这几个概念,对他们有了更深的了解,在这

大家好,又见面了,我是你们的朋友全栈君。

面向对象三大特征的理解

初始理解

其实这些知识很早就有接触,而且一些概念也牢记于心了。自己叙述面向对象的特征会是这样的:
面向对象的三大特征是封装、继承和多态。封装是对代码的封装以实现迪内聚高耦合的设计,使代码更安全且具有良好的扩展性。继承是父类产生子类的过程,子类可以使用父类的非私有的属性和方法。多态是一个对象在不同时刻可以表现出不同状态的现象。外加Animal和Cat的例子。
这一段时间敲了不少的Java代码,在敲代码的过程中想了无数次的面向对象这几个概念,对他们有了更深的了解,在这里分享一下。

封装

封装确实是对代码的封装,但是只是这样理解却又太肤浅了,至少结合Java来思考一下里面的封装嘛。
不知道大家有没有想过我们在写JavaBean的时候为什么要将属性的权限修饰为private,其实是为了使我们的代码更安全。分析如下:

public class Cat { 
   
    //这里通过private修饰属性,外界访问属性需要通过getter和setter方法
    private String name;
    private int age;
    public String getName() { 
   
        return name;
    }
    public void setName(String name) { 
   
        this.name = name;
    }
    public int getAge() { 
   
        return age;
    }
    //假设我们设置age,如果用户恶意将age设置为100
    //众所周知,impossible,因此我们可以通过setter方法进行if判断然后再赋值
    public void setAge(int age) { 
   
        this.age = age;
    }
}
我们可以考虑一下如果没有setter方法的判断,我们将该类的属性设置为public呢?那么用户的恶意输入,怎样规避呢?
总之:private是封装的一种体现。

封装还有其他的方法:为了提高代码的复用性可以将公共逻辑抽取成方法,将公共属性抽取成类。例如我们在不同的位置用到了相同的for循环,在idea中我们就可以选中相同的for循环部分,点击快捷键 ctrl + alt + m 将其抽取为方法。

继承

继承是面向对象的三大特征之一,过程就是使子类获得父类的属性和方法。
这个过程较容易理解,关键字是extends,如果我们定义的类没有显式继承某个类,系统默认为我们继承Objects。继承是我们代码的coding量变少了,提高了代码的复用性。
这里更深的体会是继承提高了代码的维护性。主要表现就是如果方法的代码需要修改,某些情况下我们只需要修改一处就可以实现。
但是这里还有一点没有想通的继承肯定会增加代码的耦合性,我们为什么还要这样夸大继承呢?我有这种疑问就是陷入了一个思维的误区,可以看这篇文章来解疑:为耦合辩护,为继承伸冤

多态

多态的三个必要条件是:

  1. 有继承或实现关系
  2. 有方法的重写
  3. 父类引用指向子类对象
class Fu { 
   
    int num = 10;
    public void method(){ 
   
        System.out.println("Fu.. method");
    }
}
class Zi extends Fu { 
   
    int num = 20;
    public void method(){ 
   
        System.out.println("Zi.. method");
    }
}
public class Test2Polymorpic { 
   
    public static void main(String[] args) { 
   
        Fu f = new Zi();
        System.out.println(f.num);
        f.method();
    }
}

关于为什么访问成员变量和成员方法的会分别get父类和子类的值和方法,这里有讲解。从虚拟机角度看Java多态->(重写override)的实现原理

  1. 好处:提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
  2. 弊端:不能使用子类的特有成员
    解决弊端可以通过向下转型:格式为子类型 对象名 = (子类型)父类引用;
class Fu { 
   
    public void show(){ 
   
        System.out.println("Fu..show...");
    }
}
class Zi extends Fu { 
   
    @Override
    public void show() { 
   
        System.out.println("Zi..show...");
    }
    public void method(){ 
   
        System.out.println("我是子类特有的方法, method");
    }
}
public class Test { 
   
    public static void main(String[] args) { 
   
        //向上转型 : 父类引用指向子类对象
        Fu f = new Zi();
        f.show();
        // 多态的弊端: 不能调用子类特有的成员
        // f.method();
        //解决方法:
        // A: 直接创建子类对象
        // B: 向下转型
        //向下转型 : 从父类类型, 转换回子类类型
        Zi z = (Zi) f;
        z.method();
    }
}

如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现ClassCastException,可以使用instanceOf来解决。

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

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

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

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

public class Test4Polymorpic { 
   
    public static void main(String[] args) { 
   
        useAnimal(new Dog());
        useAnimal(new Cat());
    }

    public static void useAnimal(Animal a){ 
   
        a.eat();
        // 判断a变量记录的类型, 是否是Dog
        if(a instanceof Dog){ 
   
            Dog dog = (Dog) a;
            dog.watchHome();
        }
    }

}

最后再来一张图体会一下多态的强大:::::
equals的参数可以是任意对象类型,这是多态的一种应用

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/159992.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 简单谈谈什么是Hystrix,以及SpringCloud的各种超时时间配置效果,和简单谈谈微服务优化[通俗易懂]

    简单谈谈什么是Hystrix,以及SpringCloud的各种超时时间配置效果,和简单谈谈微服务优化[通俗易懂]1.前言Springcloud框架中,超时时间的设置通常有三个层面:zuul网关#默认1000zuul.host.socket-timeout-millis=2000#默认2000zuul.host.connect-timeout-millis=4000ribbonribbon:OkToRetryOnAllOperations:false#对所有操作请求都进…

    2025年6月8日
    3
  • sdfsdfsd_dsd cd

    sdfsdfsd_dsd cd1)—为DataSnap系统服务程序添加描述这几天一直在研究Delphi2010的DataSnap,感觉功能真是很强大,现在足有理由证明Delphi7该下岗了。DataSnap有三种服务模式,其中ServiceApplication方式建立的windows服务没有描述,描述部分是空的,感觉总是欠缺点什么。现找到办法添加描述:procedureTServerContainer2

    2022年10月4日
    4
  • 史上MySQL安装配置教程最细,一步一图解

    史上MySQL安装配置教程最细,一步一图解一、下载MySQLMysql官网下载地址:https://downloads.mysql.com/archives/installer/1.选择要安装的版本,本篇文章选择的是5.7.31版本,点击Download下载二、安装MySQL1.选择设置类型双击运行mysql-installer-community-5.7.31.0.msi这里选择是自定义安装,所以直接选择“Custom”,点击“Next”“DeveloperDefault”是开发者默认 “Server

    2022年5月28日
    49
  • python decode函数的用法_decode函数的用法

    python decode函数的用法_decode函数的用法DECODE函数是ORACLEPL/SQL是功能强大的函数之一,目前还只有ORACLE公司的SQL提供了此函数,其他数据库厂商的SQL实现还没有此功能。DECODE有什么用途呢?先构造一个例子,假设我们想给智星职员加工资,其标准是:工资在8000元以下的将加20%;工资在8000元以上的加15%,通常的做法是,先选出记录中的工资字段值?selectsalaryintovar-salar…

    2022年7月25日
    8
  • java GC算法「建议收藏」

    java GC算法「建议收藏」一般来说,程序使用内存的方式遵循先向操作系统申请一块内存,使用内存,使用完毕之后释放内存归还给操作系统。然而在传统的C/C++等要求显式释放内存的编程语言中,记得在合适的时候释放内存是一个很有难度的工作,因此Java等编程语言都提供了基于垃圾回收算法的内存管理机制:垃圾内存回收算法常见的垃圾回收算法有引用计数法(ReferenceCounting)、标注并清理(MarkandSweep…

    2022年6月17日
    28
  • vue .js绑定checkbox并获取、改变选中状态「建议收藏」

    vue .js绑定checkbox并获取、改变选中状态「建议收藏」vue.js绑定checkbox并获取、改变选中状态1.html<divclass=”weui-cellsweui-cells_checkboxfont14″v-for=”iteminitems”><labelclass=”weui-cellweui-check__label”><…

    2022年6月18日
    106

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号