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的参数可以是任意对象类型,这是多态的一种应用

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 自己动手,丰衣足食。普通键盘实现键盘宏(Windows和Mac版)「建议收藏」

    自己动手,丰衣足食。普通键盘实现键盘宏(Windows和Mac版)「建议收藏」很多高端机械键盘,支持宏定义,例如我们可以设置”D”键为”dota”,这样当我们按一下宏开启键,再按一下”D”键,就等价于分别按了”d””o””t””a”四个键。这时就可以把一些敲代码时常用的模板定义成键盘宏,到时候一键补全代码,既高效又装X。另外,玩游戏时想按出“下前下前拳”这样的组合技能也容易多了。那么问题来了。。山里来的买不起机械键盘的穷B同时又是程序员应该怎么办。。其实这…

    2022年10月28日
  • Python实现 —【简易】12306爬虫[通俗易懂]

    Python实现 —【简易】12306爬虫[通俗易懂]最近这几天,学习了一下python,对于爬虫比较感兴趣,就做了一个简单的爬虫项目,因为快过年了么,要买回家的火车票,所以呢,通过分析12306网站,写了一个爬虫,现在,就将代码贴出来,分析的过程就不详细的介绍了,就是通过chorme浏览器进行分析。1#-*-coding:utf-8-*-2#@Date:2016-12-2714:26:333…

  • netCMS学习笔记

    netCMS学习笔记二者关系:“netCMS”出自“风讯”,“netCMS”完全开源,有相关文档资料。“风讯”开源版删除了一些源码。学习内容:一、模板实现原理   标签   netCMS自定义了一系列标签,在模版页面中插入这些标签,在发布网页时类“NetCMS.Publish.Template”用正则表达示筛选出这些标签,然后从数据库表“NT_News”中读取相应的内容,将标签替换。   模版   模版引用的CSS,图片等路径,必需是绝对路径。   前台浏览方式   分“动态”和“静态”两种模式。   在“动态”

  • 38款 流媒体服务器开源软件

    38款 流媒体服务器开源软件Flash流媒体服务器Red5Red5是一个采用Java开发开源的Flash流媒体服务器。它支持:把音频(MP3)和视频(FLV)转换成播放流;录制客户端播放流(只支持FLV);共享对象;现场直播流发布;远程调用。Red5使用RSTP作为流媒体传输协议,在其自带的一些示例中演示了在线录制,flash…更多Red5信息最近更新:Red51.0.1

  • TortoiseSVN菜单项功能说明

    TortoiseSVN菜单项功能说明

  • 进化算法_差分进化算法图解

    进化算法_差分进化算法图解神经进化正在复兴。主要的人工智能实验室和研究人员正在试验它,一丝新的成功点燃了更多的热情,能对于深度学习产生影响的新机遇正在出现。也许你在深度学习所有的激动人心的时刻并没有听到过神经进化,但它只是潜行

发表回复

您的电子邮箱地址不会被公开。

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