@

茫茫人海千千万万,感谢这一秒你看到这里。希望我的文章能对你的有所帮助!共勉!

愿你在未来的日子,保持热爱,奔赴山海!

Java基础知识(封装和继承)

一. 封装

那封装是什么呢?

在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。

1.1 封装的目的

  • 直接通过操控类对象来达到目的,不需要对具体实现十分了解,使类属性和方法的具体实现对外不可见。不但方便还起到了保护作用。
  • 封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
  • 适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

1.2 封装的好处

  • 良好的封装能够减少耦合。
  • 类内部的结构可以自由修改。
  • 可以对成员变量进行更精确的控制。
  • 隐藏信息,实现细节。

1.3 封装的步骤

  1. 修改属性的可见性来限制对属性的访问(一般限制为private),例如:

    public class Person {
    private String name ; // 姓名
    private String gender ; // 性别
    private int age; // 年龄
    }

    这段代码中,将 namesexage 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。

  2. 对每个值属性提供对外的公共方法访问,也就是创建一对赋取值方法,用于对私有属性的访问,例如:

    public class Person {
    private String name ; // 姓名
    private String gender ; // 性别
    private int age; // 年龄 public void setName(String name) {
    this.name = name;
    } public String getName() {
    return name;
    } public void setGender(String gender) {
    this.gender = gender;
    } public String gender(){
    return gender;
    } public void setAge(int age) {
    this.age = age;
    } public int getAge() {
    return age;
    }
    }

    采用 this 关键字调用本类中的属性,也就是类中的成员变量。主要为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。

1.4 封装的例子

  • 创建一个用户类User:

    代码如下:

    package com.nz.pojo;
    
    public class User {
    private String username; // 用户名
    private String password; // 密码 public String getUsername() {
    return username;
    } public void setUsername(String username) {
    this.username = username;
    } public String getPassword() {
    return password;
    } public void setPassword(String password) {
    this.password = password;
    }
    }
  • 编写测试User的demo:EncapsulationDemo

    代码如下:

    package com.nz;
    
    import com.nz.pojo.User;
    
    public class EncapsulationDemo {
    public static void main(String[] args) {
    User user = new User();
    user.setUsername("太子爷哪吒");
    user.setPassword("520");
    System.out.println("username: " + user.getUsername() + "-----------"
    + "password: " + user.getPassword());
    }
    }

    执行结果如下:

    username:太子爷哪吒-----------password520

1.5 小结

封装实际上是将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的访问和操作。就是把我们想提供给外界的一些方法给暴露出来,以便外界能调用到我们。

二. 继承

2.1 继承的介绍

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。描述的是事物之间的所属关系,这种关系是:is-a 的关系。

继承:就是子类继承父类的属性行为,使得子类对象(实例)可以直接具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。

2.2 生活中的继承

兔子和长颈鹿属于食草动物类,老虎和狮子属于食肉动物类。而食草动物和食肉动物又是属于动物类。

那是不是兔子、长颈鹿、老虎、狮子都属于动物类呢?答案是没错滴!虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。我们就可以再多个类中存在相同属性和行为时,我们可以将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。

2.3 继承的好处

  1. 提高代码的复用性(减少代码冗余,相同代码重复利用)。
  2. 使类与类之间产生了关系。
  3. 子类拥有父类非 private 的属性、方法。
  4. 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
  5. 子类可以用自己的方式实现父类的方法。
  6. 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
  7. Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

2.4 继承的格式

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

class 父类 {
} class 子类 extends 父类 {
}

需要注意一点: Java 不支持多继承,但支持多重继承。就如下:

class A {
} class B extends A { (对的)
} class C extends A, B { (错的)
} class C extends B { (对的)
}

顶层父类是Object类。所有的类默认继承Object,作为父类。

2.5 继承的demo

  • 编写一个父类极其对应的子类信息

    结构如下:

    代码如下:

    父类Person:

    package com.nz.pojo;
    
    public class Person {
    private String name ;
    private int age ; public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public int getAge() {
    return age;
    } public void setAge(int age) {
    this.age = age;
    }
    }

    子类Student没有额外的属性和方法:

    package com.nz.pojo;
    
    /**
    * 继承了Person特有的name, age,
    * 没有额外的独有属性和方法
    */
    public class Student extends Person{
    }

    子类Teacher多了一个工资的属性和独有的教书方法:

    package com.nz.pojo;
    
    /**
    * 继承了Person特有的name, age,
    * 多了自己独有的工资属性还有独有的教书方法
    */
    public class Teacher extends Person{ // 工资
    private double salary ; // 特有方法
    public void teach(){
    System.out.println("老师在认真教书!");
    } public double getSalary() {
    return salary;
    } public void setSalary(double salary) {
    this.salary = salary;
    }
    }
  • 编写测试代码:

    package com.nz;
    
    import com.nz.pojo.Student;
    import com.nz.pojo.Teacher; public class InheritDemo {
    public static void main(String[] args) {
    Teacher teacher = new Teacher();
    teacher.setName("太子爷哪吒");
    teacher.setAge(18);
    teacher.setSalary(1999.99);
    System.out.println(teacher.getName());
    System.out.println(teacher.getAge());
    System.out.println(teacher.getSalary());
    teacher.teach(); Student student = new Student();
    student.setName("哪吒");
    student.setAge(12);
    //student.setSalary(1999.99); // student没有工资属性,报错!
    System.out.println(student.getName());
    System.out.println(student.getAge());
    }
    }

    结果如下:

    太子爷哪吒
    18
    1999.99
    老师在认真教书!
    哪吒
    12

    从结果来看,子类继承父类,就可以直接得到父类的成员变量和方法。而子类可以编写一些特有的属性和方法,但是是否可以继承所有成分呢?

2.6 子类不能继承的内容

并不是父类的所有内容都可以给子类继承的:

2.6.1 super 与 this 关键字

这里先将这两个关键字,super和this在继承关系中,运用比较频繁。

  • super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

  • this关键字:指向自己本类的引用。

    super和this完整的用法如下:

    this.成员变量    	--    本类的
    super.成员变量 -- 父类的 this.成员方法名() -- 本类的
    super.成员方法名() -- 父类的
  • 具体演示,创建测试InheritDemo2:

    package com.nz;
    
    public class InheritDemo2 {
    public static void main(String[] args) {
    Animal a = new Animal();
    a.eat();
    Cat cat = new Cat();
    cat.eatFish();
    }
    } class Animal {
    void eat() {
    System.out.println("animal : eat");
    }
    } class Cat extends Animal {
    void eat() {
    System.out.println("cat : eat");
    }
    void eatFish() {
    this.eat(); // this 调用自己的方法
    super.eat(); // super 调用父类方法
    }
    }

    调用结果如下:

    animal : eat
    cat : eat
    animal : eat
  • 注意:

    子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。

    super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。

2.6.2 构造器不能被继承

  • 子类不能继承父类的构造器(构造方法或者构造函数),它只是调用(隐式或显式)。因为子类有自己的构造器。值得注意的是子类可以继承父类的私有成员(成员变量,方法),只是子类无法直接访问而已,可以通过getter/setter方法访问父类的private成员变量。

  • 如果父类的构造器带有参数,则必须在子类的构造器中显式地通过super 关键字调用父类的构造器并配以适当的参数列表。

  • 如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

  • 演示过程:

    package com.nz;
    
    public class InheritDemo3  {
    public static void main(String[] args) {
    System.out.println("------Teacher 类继承------");
    Teacher teacher = new Teacher();
    Teacher teacher2 = new Teacher("张三");
    System.out.println("------Student 类继承------");
    Student student = new Student();
    Student student2 = new Student("张三三");
    }
    }
    // 父类
    class Person {
    private String name;
    Person(){
    System.out.println("调用了父类的无参构造器: Person()");
    }
    Person(String name) {
    System.out.println("调用了父类的带参构造器: Person(String name)");
    this.name = name;
    }
    }
    // Teacher子类继承Person
    class Teacher extends Person{
    private String name;
    Teacher(){
    // 自动调用父类的无参数构造器 因为会有默认super();
    System.out.println("Teacher");
    } public Teacher(String name){
    super("太子爷哪吒"); // 调用父类中带有参数的构造器
    System.out.println("Teacher(String name):"+name);
    this.name = name;
    }
    }
    // Student子类继承Person
    class Student extends Person{
    private String name; Student(){
    super("heihei"); // 调用父类中带有参数的构造器
    System.out.println("SubClass2");
    } public Student(String name){ // 自动调用父类的无参数构造器
    System.out.println("Student(String name):"+name);
    this.name = name;
    }
    }

    结果如下:

    ------Teacher 类继承------
    调用了父类的无参构造器: Person()
    Teacher
    调用了父类的带参构造器: Person(String name)
    Teacher(String name):张三
    ------Student 类继承------
    调用了父类的带参构造器: Person(String name)
    SubClass2
    调用了父类的无参构造器: Person()
    Student(String name):张三三

2.6.3 final修饰的类不能被继承

final 关键字主要用在三个地方:变量、方法、类。

  1. 修饰类:表示该类不能被继承;
  2. 修饰方法:表示方法不能被重写;
  3. 修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。

final 的特点:

  • 对于一个 final 变量,如果是基本数据类型的变量,则其数值一旦在初始 化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不 能再让其指向另一个对象。
  • 当用 final 修饰一个类时,表明这个类不能被继承。final 类中的所有成员 方法都会被隐式地指定为 final 方法。
  • 使用 final 方法的原因有两个。第一个原因是把方法锁定,以防任何继承 类修改它的含义;第二个原因是效率。在早期的 Java 实现版本中,会将 final 方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用 带来的任何性能提升(现在的 Java 版本已经不需要使用 final方法进行这些优化了)。类中所有的 private 方法都隐式地指定为 final。

我们测试下修饰类后到底能不能继承:

package com.nz;

public class InheritDemo4 {
} // 父类
final class Fu {
private String name;
} //class Zi extends Fu{ // Cannot inherit from final 'com.nz.Fu' 会显示没办法继承Fu
//}

结果:可以看出来在被final修饰的Fu类没办法继承,而且在编译期间就会报错了,没办法通过运行。

2.7 方法重写

2.7.1 介绍

子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现

2.7.2 使用场景与案例

发生在子父类之间的关系。

子类继承了父类的方法,但是子类觉得父类的这方法不足以满足自己的需求,子类重新写了一个与父类同名的方法,以便覆盖父类的该方法。

写个测试案例:

package com.nz;

public class InheritDemo5 {

    public static void main(String[] args) {
// 创建子类对象
Cat lanMao = new Cat();
// 调用父类继承而来的方法
lanMao.run();
// 调用子类重写的方法
lanMao.sing(); }
} class Animal{
public void sing(){
System.out.println("动物都可以唱歌!");
}
public void run(){
System.out.println("动物都可以跑!");
}
} class Cat extends Animal {
public void sing(){
System.out.println("我们一起学猫叫,一起喵喵喵!让我们一起撒个娇");
}
}

运行结果:

动物都可以跑!
我们一起学猫叫,一起喵喵喵!让我们一起撒个娇

可以看出,蓝猫调用了重写后的sing方法。

2.7.2 @Override重写注解

  • @Override:注解,重写注解校验

  • 这个注解标记的方法,就说明这个方法必须是重写父类的方法,否则编译阶段报错。

  • 建议重写都加上这个注解,一方面可以提高代码的可读性,一方面可以防止重写出错!

    加上后的子类代码形式如下:

    class Cat extends Animal {
    // 声明不变,重新实现
    // 方法名称与父类全部一样,只是方法体中的功能重写了!
    @Override
    public void sing(){
    System.out.println("我们一起学猫叫,一起喵喵喵!让我们一起撒个娇");
    }
    }

2.7.3 注意事项

  1. 方法重写是发生在子父类之间的关系。
  2. 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
  3. 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。

2.8 小结

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

注: 如果文章有任何错误和建议,请各位大佬尽情留言!如果这篇文章对你也有所帮助,希望可爱亲切的您给个三连关注下,非常感谢啦!也可以微信搜索太子爷哪吒公众号进行私聊我,感谢各位大佬!

Java基础-封装和继承的更多相关文章

  1. Java面向对象封装和继承

    面向对象 什么是面向过程.面向对象? 面向过程与面向对象都是我们编程中,编写程序的一种思维方式. 面向过程的程序设计方式,是遇到一件事时,思考“我该怎么做”,然后一步步实现的过程.例如:公司打扫卫生( ...

  2. Java之封装,继承,多态

    一,前言 ​ 今天总结一下关于Java的三大特性,封装,继承,多态.其实关于三大特性对于从事编程人员来说都是基本的了,毕竟只要接触Java这些都是先要认识的,接下来就系统总结一下. 二,封装 ​ 先来 ...

  3. Java基础笔记-抽象,继承,多态

    抽象类: abstract修饰 抽象方法必须定义在抽象类中,抽象类不能创建对象. 在抽象方法中可以不定义抽象方法,作用是:让该类不能建立对象. 特点是: 1.定义在抽象类中 2.方法和类都用abstr ...

  4. Java基础学习笔记七 Java基础语法之继承和抽象类

    继承 继承的概念 在现实生活中,继承一般指的是子女继承父辈的财产.在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系. 例如公司中的研发部员工和维护部员工都属于员工, ...

  5. Java基础教程(18)--继承

    一.继承的概念   继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...

  6. java中封装,继承,多态,接口学习总结

    ### 一:封装java中封装是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问.要访问该类的代码和数据,必须通 ...

  7. Java基础系列 - 抽象类继承和接口实现

    package com.inter; /** * 继承和接口的关系,单继承,多接口 * java不支持多继承,但可通过接口实现多重继承 */ public class test2 { public s ...

  8. Java基础第一天--继承、修饰符

    继承 继承的概述: 继承是面向对象三大特征之一.可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法. //创建父类 public class Fu{ public void sh ...

  9. java基础(六)之继承初探

    什么是继承? 一个类得到了另一个类当中的成员变量和成员方法.java只支持单继承.一个子类只允许继承一个父类,一个父类可以被多个子类继承. 比如下面的一个例子, 先创建一个Person类 class ...

随机推荐

  1. IIS部署.Net5全流程

    介绍 Internet Information Services (IIS) 是一种灵活.安全且可管理的 Web 服务器,用于托管 Web 应用(包括 ASP.NET Core).虽然我们的程序可以跨 ...

  2. JPEG头部解析

    6.3 JPEG格式       6.3.1简介  微处理机中的存放顺序有正序(big endian)和逆序(little endian)之分.正序存放就是高字节存放在前低字节在后,而逆序存放就是低字 ...

  3. Handle详解

    首先通过一个函数启动一个服务器,只提供一个方法并返回Hello World!,当你在浏览器输入http://127.0.0.1:8080,就会看到Hello World. 对于http.ListenA ...

  4. [刷题] 剑指offer 面试题18:删除链表节点

    要求 给定单向链表的头指针和一个节点指针,在O(1)时间内删除该节点 常规思路:从头节点a开始顺序遍历,发现p指向要删除的节点i,然后把p的m_pNext指向i的下一个节点j,时间复杂度O(n) O( ...

  5. Linux讲解之定时任务

    https://www.php.cn/linux-369884.html Linux讲解之定时任务 原创2018-05-14 10:11:3101319 本文目录: 12.1 配置定时任务 1 ...

  6. Zabbix 监控系统部署

    Zabbix 监控系统部署 实验环境 Zabbix server:RHEL8 ip:192.168.121.10 一.关闭防火墙和selinux [root@Zabbix-server ~]# sys ...

  7. 云计算OpenStack环境搭建(4)

    准备工作: 准备3台机器,确保yum源是可用的,分别为控制节点(192.168.11.3).计算节点(192.168.11.4)和存储节点(192.168.11.5) 控制节点:OpenStack日常 ...

  8. Linux进阶之软件管理

    本节内容 一.rpm:管理linux软件程序的 特点:安装方便 不能解决依赖关系 1.安装软件: -i: -v: -h: rpm -ivh 包名 2.卸载软件 -e: 清楚 rpm -e 程序名 3. ...

  9. 8.10-11 mount、umount

    8.10 mount:挂载文件系统 mount命令可以将指定的文件系统挂载到指定目录(挂载点),在Linux系统下必须先挂载所有的设备,然后才能被访问,挂载其实就是为要访问的设置开个门(开门才能访问) ...

  10. IntelliJ IDEA配置tomcat 教程

    1.点击Run-Edit Configurations... 2.点击左侧"+",选择Tomcat Server--Local 3.在Tomcat Server -> Unn ...