千家信息网

Java语言之包和继承的示例分析

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章主要介绍了Java语言之包和继承的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、包包名在讲包名前,我们先来了解一下
千家信息网最后更新 2025年02月01日Java语言之包和继承的示例分析

这篇文章主要介绍了Java语言之包和继承的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

    一、包

    包名

    在讲包名前,我们先来了解一下,包是用来干什么的?

    Java中允许使用包(package),包将类组织在一个集合中。借助包可以方便管理组织自己的代码,并将自己的代码与别人的提供的代码库分开管理。

    包是组织类的一种方式。使用包的主要目的就是保证类的唯一性。

    在Windows操作系统中,我们都知道,同一个文件夹下,不能同时出现两个一样的文件名的文件。而我们的java类,对应的就是一个.class文件,所以产生了包,而包其实就可以理解为路径中所存放的文件夹,为了出现重命的类名,所以将各个类分布在不同的包(文件夹)中。

    而包名的命名:包名必须全部是小写字母,且一般包的命名方式是所在公司的官网(域名)的逆序写,假如www.xxxx.com,一般包名就是com.xxxx.--等等。

    从编译器的角度来看,嵌套的包之间没有任何关系。例如:java.util包和java.util.jar包毫无关系。每一个包都是独立的类集合。

    类的导入与静态导入

    一个类可以使用所属包中的所有类,以及其他包下的公共类(public class)。

    访问另一个包的类有两种方式:

    1.使用完全限定名,也就是说在包名后面跟着类名。

    java.util.Scanner scan = new java.util.Scanner(); //类名前面,直接跟包名

    2.使用import关键字

    import语句应该位于源文件的顶部,且位于package语句的后面。

    import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner sc = new scanner();    }}

    对于导包,我们还有一种比较简单的方式,如下

    import java.util.*;

    *,就是通配符。也就是在当前类中,可以直接使用util包的所有类,从而不需要再次导包了。值得注意的是,这里的导入,并不是导入util包下的所有类,这里跟C语言的include,不一样。C语言中的include,是导入头文件下的所有内容;而这里的import导入,只会在需要使用这个包下的类的时候,才会导入进来

    当然,对于import导入包时,还需要特别注意一个问题,如下:

    import java.util.*;import java.sql.*;public class Main {    public static void main(String[] args) {        Date date = new Date(); //error, java.util.Date 还是 java.sql.Date?    }}

    此时进行编译,就会产生一个如上面代码的注释部分的错误。此时的编译器无法确定你想使用的是哪一个包下的Date类。现在就可以添加一个特定的import来解决这个问题。

    import java.util.*;import java.sql.*;import java.util.Date; //特别指出是使用这个包下的Date类public class Main {    public static void main(String[] args) {        Date date = new Date();    }}

    如果此时,两个包中的Date都需要使用,那就只能使用完全限定名了。如下:

    import java.util.*;import java.sql.*;public class Main {    public static void main(String[] args) {        java.util.Date date = new java.util.Date();        java.sql.Date  date2 = new java.util.Date();    }}

    静态导入

    我们还可以使用静态导入包的方式,进行代码的缩写。使用import static 可以导入包中的静态方法和静态字段。这样就可以不必再加类名前缀。

    import static java.lang.System.*;public class Main {    public static void main(String[] args) {        out.println("hello world");    }}

    只是有这样一种机制,可以进行代码的缩写,但在现实中,这样的代码,可能更不容易读懂。所以大家使用时,酌情考虑。

    在包中添加类

    如果要想将类放入包中,就必须将包的名字放在源文件的开头,即就是放在定义这个包中各个类的代码之前。如下:

    如果没有在这个源文件的开头,写package语句,则这个源文件中类就属于无名包(unnamed package)。无名包没有包名。

    基本规则:

    • 在源文件的最上方加一个package语句,可以指定该代码在哪个包

    • 包名尽量指定成唯一的名字,通常会使用公司的域名逆序形成

    • 包名要和代码路径相匹配。例如:package com.xxxx.demo,那么所对应的文件路径就是com/xxxx/demo

    • 如果一个源文件没有package语句,则该类会被放到无名包(默认包)中

    IDEA建包过程:

    包访问权限

    在之前的文章中,我们介绍过publicprivate。而private修饰的方法或成员变量,只能在当前这个类中访问。

    如果有个类,既没有写public,也没有写private访问修饰限定符,则此时这个(类、方法或成员变量)可以在包内部(当前文件夹下)的其他类中使用,但是不能在包外部(其他文件夹下)的类中使用。如下代码:

    import com.xxxx.demo1;//demo1 包public class Main {    public static void main(String[] args) {        Test test = new Test(); //会报错,访问权限不够。    }}//=====假设下面是第二个文件夹下的文件=====import com.xxxx.demo2;class Test { //访问修饰限定符:没写,我们就称为 默认    public int number;}public class Demo2 {    public int val;}

    访问修饰限定符权限:

    范围private默认(default)protectedpublic
    同包同类YYYY
    同包不同类
    YYY
    不同包,子类

    YY
    不同包,不同类


    Y

    其中,protected会在继承中讲到,我们继续往下看!!!

    二、继承

    继承的基本思想就是:在已有类的基础之上,创建新的类。继承已存在的类得到就是复用了(继承)这些类的方法,而且可以增加一些新的方法和成员变量。

    类、超类与子类

    我们先来举个例子,比如一只猫和一只狗。它们了分别有自己的名字、性别、还是吃东西等等的一些性质。如下图:

    他们分别都有自己的这些特征,我们也可以很容易的发现,他们都有自己一些共有的特征:比如姓名,性别。所以如果我们分别在新建猫和狗的类,还得写专属于它们自己的成员变量,这样的话,就显得代码重复累赘,如下图这样:

    我们可以很清晰的看到,红色框代码部分,就是一模一样的,所以出现了重复的代码。而且这两个类都是动物,所以说引出了一个继承中的一个概念:"is -a"关系。

    也就是说,什么是一个什么这样的概念。就可能会用到继承。

    那该怎么实现继承关系呢?我们来看下图:

    我们可以使用extends关键字来实现继承关系,这样的话,猫和狗两个类,就能够同时实现name和sex字段。这就是继承。

    此时猫和狗类,我们称为子类或者派生类。而Animal类我们称为父类基类超类

    总结:

    • 使用extends指定父类

    • Java中一个子类只能继承一个父类。(而C++中可以实现多继承)

    • 子类会继承父类所有的public的字段和方法

    • 对于父类的private的字段和方法,子类是无法进行访问的

    • 子类的实例中,也包含这父类的实例。可以使用super关键字得到父类实例的引用。

    重写方法(override)

    像上图,子类和父类中,方法名和参数列表是一模一样的。我们就称为方法重写(override)。可能有人就会问,我该怎么调用相应的方法呢?

    我们想调用Animal的eat方法,我们只需要new出一个Animal的对象,就能进行调用,当然,Cat类的实例对象也是如此。如果我们想在Cat类的实例对象调用父类的方法,则我们可以使用super关键字进行调用。如下图:

    切记:

    • super关键字,在使用的时候,只能调用他的直接父类的方法或字段。比如:Animal类还继承了一个类,此时Cat类中,使用super,则只会调用Animal中的方法或字段。

    • 在子类中重写的方法,这个方法的访问修饰限定符的等级,应高于或等于父类的方法的访问修饰限定符。比如:父类中的eat方法是public修饰,而子类中的eat方法也应该是public,或者是更高的。(当然只是举个例子,public就是最高的访问修饰限定符了)

    • 被重写的方法,不能是被static修饰的

    this与super的区别:

    子类构造器

    在上面说了,super关键字来调用父类的构造方法,那具体是如何进行调用的,我们来看一下具体的代码实现:

    public class Cat extends Animal{    public Cat(String name, String sex) {        super(name, sex); //调用父类的构造方法,super语句必须在子类构造器的第一行        System.out.println("Cat的构造方法");     }    public void eat() {        System.out.println("吃鱼");    }}
    public class Animal {    public String name;    public String sex;    public Animal(String name, String sex) { //父类的构造方法        this.name = name;        this.sex = sex;    }    public void eat() {        System.out.println("吃肉");    }}

    总结:

    • 使用super构造方法的语句必须放在子类构造方法中的第一行。

    • 如果子类中,没有显示地调用父类的构造方法,将自动地调用超类的无参构造方法。

    • 在进行子类的实例化时,会调用子类的构造方法,而在调用子类构造方法时,将会先调用父类的构造方法。也就是说:new Cat ,实际上将先会新建出父类,在父类新建完成后,才会回到子类的构造方法,进行新建子类。

    下面是一道有趣的题:请问下列代码的输出结果是什么。

    class X {    Y y=new Y();    public X() {        System.out.print("X");    }}class Y {    public Y() {         System.out.print("Y");    }}public class Z extends X {    Y y=new Y();    public Z() {        System.out.print("Z");    }    public static void main(String[] args) {        new Z();    }}

    上面的代码的输出结果是:YXYZ。

    分析:

    • 如果调用的是子类,那么在进入子类构造方法后,将先执行super语句(若没写,编译器自带),先构造父类。

    • 在父类构造完成后,再次回到子类的构造方法。此时将先初始化当前类的成员变量。

    • 在成员变量初始化之后,才会执行构造方法里面的语句。

    上诉代码执行流程图:

    protected关键字

    在上文中,我写了一个访问修饰限定符的表,表中第3个protected关键字。

    前面我们学了public和private访问修饰限定符,public的权限有大了,对于public来说,整个工程都可以进行使用;而对于private来说,只能在当前的类中进行使用。二者之前,一个权限过大,一个权限过小。所以在Java的继承中,还引入了这个关键字:protected;

    对于protected来说,protected修饰的内容,在这个包下,可以直接使用。而在不同的包下,只有继承了这个类,才能在不同的包下使用该类被protected修饰内容。

    阻止继承:final关键字

    在前面的文章中,我们介绍过final关键字,final修饰的变量,在初始化之后,将不能被修改。

    final int a = 10;a = 20; //编译出错,此时的a被final修饰,存储在方法区,且不能被修改

    final也能修饰类,,表示不能再被继承,称为密封类。

    final还能修饰方法,表示此时的方法不能被重写,称为密封方法。

    切记:如果一个类被final修饰,那么其中的方法将自动地称为final,但是不包括字段。如果一个方法没有被重写并且还很短,编译器将会对此进行优化处理,这个过程称为内联

    组合

    和继承类似的,还有一个叫组合的概念,也是用于表达类之间的关系,也能够达到代码的重复使用。

    例如:一个公司由很多人组合而成,有当经理的、职员的、保洁员的等等……

    class Person {    public String name;    public String sex;}class Manager extends Person { //继承 人    //经理的薪水    public double getSalary() {    }}class Staff extends Person { //继承 人    //普通职员的薪水    public double getSalary() {    }}//组合public class Company {    public Manager[] manager; //经理    public Staff[] staff; //普通职员}

    组合并没有涉及到特殊的语法,仅仅只是将一个类的实例作为另一个类的字段,这也是我们设计类的一种常用的方式或思想。

    组合表示has- a 的语义:意为:一个事物 由 什么组合而成,也就是包含的意思。

    继承表示is-a的语义:意为:一个事物 是 一个什么事物的概念。

    感谢你能够认真阅读完这篇文章,希望小编分享的"Java语言之包和继承的示例分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

    方法 子类 代码 文件 关键 关键字 就是 语句 字段 变量 实例 成员 文件夹 方式 权限 源文件 组合 编译 不同 也就是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 淮安涵金量软件开发公司 只狼不联网能不能跳过登录服务器 上海万晓网络技术有限公司 南充 网络技术有限公司 数据库的内存怎么查 服务器版360安全卫士 网络安全方面的论文题目有哪些 网络安全交易义务的重要性 数据库中怎么查所有序列号 免费代理我的世界服务器 电气数据库技术 浏览器解密服务器发送的用户信息 网络安全漏洞发布平台 我的世界星球服务器怎么进 阿里巴巴服务器里面的黑科技 宿舍管理数据库的设计 率土之滨各个服务器在哪下载 江西省工信厅网络安全 社保费管理客户端链接服务器异常 闵行区推广网络安全技术指导 网络安全执法检查信息 从网络安全知识学到了什么 网络安全面临的问题和威胁 我国网络安全如何避免黑客 数据库数据推送同步阿里 用户登录查询数据库网页 绍兴定制软件开发报价 软件开发部经理待遇 西电电子科技大学网络安全 杭州以息互联网科技招聘
    0