Java面向对象编程——封装和继承

面向对象是编程的重点,涉及到类的封装继承抽象多态接口的设计等。其中,封装、继承、多态是面向对象的三大特征。MVC架构中的"Model"部分的设计,实际上就是基于对象的设计,就是面向对象编程。而面向对象编程,是一门较深的学问。面向对象编程的方法可以通过具体实例总结,而在不同的具体环境及需求中,对象设计及方法的应用,是需要长期的实践经验来积淀。通过不断熟练面向对象编程思维,权衡功能以尽可能实现需求,来完善代码,进一步增强代码可读性和简洁性、实用性。因此,“武功秘诀”虽简单,但练就绝非一朝一夕。

本文基于Java面向对象编程,引用了一些实例及相应方法,以尽可能总结Java面向对象编程封装继承的要素。

封装

  • 封装:是一种面向对象编程方法,对类的具体实现细节部分进行包装隐藏,只暴露方法接口,但方法的实现不完全暴露给用户。

  • 前提:正确地表达现实生活中的问题,并保证代码的拓展性和可维护性。

  • 整体思路:是将把代码分成两个部分:接口实现,以类的形式进行封装。其中,接口将涉及和外部的交互,属于对用户暴露的部分,应该保持稳定,因此修改维护代码的时候,可以只改变内容而不改变接口,使用方式不变;内部实现不需要暴露给外部用户,在接口功能不被影响的前提下,可以随意修改和重构

  • 封装方法:对类的内部状态的访问进行控制,根据需求只提供该提供的信息。采用privatefinal等修饰符对相应成员变量或方法进行访问或修改控制,再用gettersetter等方法作为接口,赋予私有变量的可读或可写权限。final限制了setter的使用,进一步防止私有变量被修改。

  • 原因:可以防止用户使用的时候出错,或降低出错的可能。用户在调用编写的类的时候,有一定概率会出错,不能低估用户的想象力。但在团队合作中,必须考虑什么事情该自己承担,什么是用户的责任,什么是自己的责任。因此设计产品的时候,优先设计为private隐藏信息,再考虑是否有暴露出去的必要,根据具体需求改成public或其他访问权限。

  • 原则高内聚,低耦合,良好的封装是解耦的基础
    低耦合:保留必须的方法
    高内聚:大部分具体实现代码可以修改

  • 应用场景
    1.发现代码有问题,需要进行错误修正优化算法来改变实现
    2.发展新能力,通过修改方法内容来实现,例如读取文件的方式可以从txt文档读取,发展为从word文档中读取,或从本地文件读取发展为网络信息读取

封装代码实例

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class News {
    private String title;                                         
    private String content;                                       //private限制了外部访问
    
    public News(){}                                               //缺省构造函数

    public News(String title,String content) {                    //构造函数初始化成员变量
        this.title = title;
        this.content = content;
    }

    //可改变title和content,相当于一种setter方法
    //title和content被final修饰时,此方法会报错
    public void read(String fileUrl) throws IOException{          
        try {
            //从Url读取内容
            BufferedReader  reader = new BufferedReader(new FileReader(new File(fileUrl)));
            title = reader.readLine();                            //赋值给title
            content = reader.readLine();                          //赋值给content
        }
        catch (IOException e) {
            System.out.println("新闻读取出错");                     //异常抓取
        }
    }

    public String getTitle() {                                    //getter方法,为title提供可读接口
        return title;
    }

    public String getContent() {                                  //getter方法,为content提供可读接口
        return content;
    }

    //控制如何显示,显示格式,相当于一种getter方法
    public String display() {
        return title + "\n" + content;
    }
}

测试代码

import java.io.IOException;

public class Main {

    public static void main(String[] args) throws IOException {
        News news = new News("abc","blabla");
        System.out.println(news.display());
        news.read("");
        System.out.println(news.display());
    }
}

测试结果

abc
blabla
新闻读取出错
  • 总结尽可能向用户暴露更少的信息
    原因
    1.给予用户的接口越少,他操作时基于的东西就越少,他需要知道的知识越少,这个程序在使用上就越简洁,使用成本越低
    2.暴露的代码越少,客户依赖于我们写的代码就会越少,我们在修改维护时就可以进行更灵活的更改。而任何暴露给用户的内容,基本上是不能更改的,或者说更改暴露内容是万不得已的选择

继承

  • 继承:是Java面向对象编程技术的一块基石,因为他允许创建分等级层次的类,即分层

  • 方法:在声明子类的时候,通过关键字extends表达继承

  • 特性
    1.子类拥有父类非private的成员变量和方法
    2.子类可以拥有自己的成员变量和方法,即子类可以对父类进行扩展
    3.子类可以重新实现父类的方法,override
    4.Java只支持单继承,即只能有一个父类,省去了多继承带来的麻烦(C++不一样,可以多继承)
    5.super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类
    6.this关键字:指向自己的引用
    7.final <类>:防止类被继承

  • 关系is-a
    父类具有子类的公共变量和方法,子类是更具体的父类,子类继承父类的特征和行为,使得子类对象具有父类对象的特征和方法,并拓展额外的功能。因此设计时将对象的公共部分抽象出来,从子类抽象出父类,会更直接更符合设计的直觉

  • 原则:没有重复代码

  • 构造方法:先有的父类,才有的子类,因此要先初始化父类,在子类的构造器中显式地通过super关键字调用父类的构造器并配以适当的参数列表。
    其中,子类不能继承父类的构造器(构造方法或者构造函数),如果父类的构造器带有参数,则必须在子类的构造器中显示地通过super关键字调用父类的构造器并配以适当的参数列表。如果父类的构造器没有参数,则在子类的构造器中不需要使用super关键字调用父类构造器,系统会自动调用父类的无参构造器(并不是不用)

父类代码实例

public class News {
    protected String title;         //可被子类访问
    protected String content;

    //无参构造器
    public News(){}

    // 构造的自由和责任交给用户
    public News(String title, String content) {
        this.title = title;
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }

    // 控制如何显示
    public String display() {
        return title + "\n" + content;
    }
}

子类代码实例

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class FileNews extends News{
    public FileNews(String title ,String content) {
        super(title, content);                  //调用父类构造函数
    }

    public FileNews() {}                        //默认有个super()

    public void read(String url) throws IOException {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(new File(url)));
            title = reader.readLine();          // 读取title
            reader.readLine();                  // 跳过空行
            content = reader.readLine();        // 读取content
        }
        catch (IOException e) {
            System.out.println("新闻读取出错");  // 异常处理
        }
    }

    public String display() {                   // display()方法的override
        return super.display() + "from 子类";
    }
}

测试代码

import java.io.IOException;

public class Main {

    public static void main(String[] args) throws IOException {
        News news = new News("abc","父类");
        System.out.println(news.display());

        FileNews fileNews = new FileNews("123","子类");
        System.out.println(fileNews.display());
    }
}

测试结果

abc
父类
123:子类
  • 总结:继承为了继承成员变量,可能会牺牲private和final,protected修饰,但会牺牲部分安全性(只能用注释声明告诉用户不要修改它),因此这又是一个权衡的过程与责任的分配,因此在写类的时候要考虑其是否将来会被继承,来决定变量的访问限制。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,547评论 4 374
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,787评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,175评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,752评论 0 223
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,169评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,056评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,195评论 2 321
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,980评论 0 214
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,724评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,872评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,344评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,667评论 3 264
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,379评论 3 245
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,202评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,992评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,189评论 2 286
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,987评论 2 279

推荐阅读更多精彩内容