封装继承多态

一给  金牌会员 | 2022-8-26 01:21:14 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 860|帖子 860|积分 2580

面向对象三大特征:封装、继承、多态


目录

访问控制符


  • 在讲封装之前我们先了解一下关于访问控制符
​        Java 提供了 3 个访问控制符:private、 protected 和 public ,代表 3 种不同的访问级别,再加上一个默认的访问控制级别(不使用任何访问控制符),共有 4 个访问控制级别。

  • private(当前类访问权限):类中的一个的成员被 private 修饰,它只能在当前类的内部被访问;
  • default(包访问权限):类中的一个成员或者一个外部类不使用任何访问控制符修饰,它能被当前包下其他类访问;
  • protected(子类访问权限):类中的一个的成员被 protected 修饰,它既可以被当前包下的其他类访问,又可以被不同包的子类访问;
  • public(公共访问权限):类中的一个成员或者一个外部类使用 public 修饰,它能被所有类访问。
我们可以用一个表,来看一下访问修饰符
一个类中同一个包中其他包的子类中全局范围private√default√√protected√√√public√√√√看完了修饰符,我么开始学习封装
封装


  • 程序设计追求:高内聚,低耦合。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉!低耦合:仅暴露少量的方法给外部使用!
封装的定义

封装指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。
封装的意义


  • 1.提高代码的安全性,保护数据
  • 2.隐藏代码的实现细节
  • 3.统一接口
  • 4.增加系统可维护性
下面我们用代码来实际看一下关于封装的应用:
首先定义一个学生类,在类中我们定义了三个属性,但是属性的修饰符是private
也就是私有的,我们只能在类中去使用这个方法,那么我们在测试类中想要调用它,这时我们可以定义一个公共的方法来使用它
  1. public class Student {
  2.     //private关键字,定义私有属性
  3.     //名字
  4.     private String name;
  5.     //学号.
  6.     private String id;
  7.     //性别
  8.     private String sex;
  9.    }
复制代码
  1. public class Student {
  2.     //private关键字,定义私有属性
  3.     //名字
  4.     private String name;
  5.     //学号.
  6.     private String id;
  7.     //性别
  8.     private String sex;
  9.   //通过get用来获取类中的name
  10. public String getName() {
  11.     return this.name;
  12. }
  13. //set给这个属性设置值
  14. public void setName(String name) {
  15.     this.name = name;
  16. }
  17. }
复制代码
现在我们可以在测试类中,看一下,
  1. public class Application {
  2.     public static void main(String[] args) {
  3.         Student student=new Student();
  4.         student.setName("lingstar");
  5.         System.out.println(student.getName());
  6.     }
  7. }
复制代码
输出:
  1. lingstar
复制代码
我们在操作中也可以使用快捷键,AIL+INSERT然后点击Getter或者Setter或者Getter and Setter来快速添加此方法
封装可以也可以对传入其中的数据进行判断,看数据是否合理?
eg:以传入的性别为例
性别只有男或者女,当传入性别为其他时候,我们返回"您输入的性别有误"
我们在类中添加一下代码
代码:
  1. public String getSex() {
  2.     return sex;
  3. }
  4. public void setSex(String sex) {
  5.     switch (sex) {
  6.         case " 男":
  7.             this.sex = sex;
  8.             break;
  9.         case "女":
  10.             this.sex=sex;
  11.             break;
  12.         default:
  13.             System.out.println("您输入的性别有误!");
  14.     }
  15. }
复制代码
然后实际运行看一下:
测试代码:
  1. public class Application {
  2.     public static void main(String[] args) {
  3.         Student student=new Student();
  4.         student.setSex("what");
  5.         System.out.println(student.getSex());
  6.     }
  7. }
复制代码
输出:
  1. 您输入的性别有误!
  2. null
复制代码
当输入正确的信息时:
  1. public class Application {
  2.     public static void main(String[] args) {
  3.         System.out.println(student.getName());
  4.         student.setSex("男");
  5.         System.out.println(student.getSex());
  6.     }
  7. }
复制代码
输出:
  1.         男
复制代码
通过这么一个简单的例子,想要了解全部的封装的意义不太现实,这就需要我们在空闲时间多去练习和使用封装!
继承


  • Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。
  • Java 使用 extends 作为继承的关键字子类继承了父类,就会获得父类的全部成员变量和方法
  • java只有单继承没有多继承
  • 私有的(private)东西是无法继承的
代码示例:
我们首先定义一个Person类
  1. public class Person {
  2.     public void run(){
  3.         System.out.println("人会奔跑");
  4.     }
  5. }
复制代码
然后定义一个Student类,让学生类继承Person类
  1. public class Student extends Person{
  2. }
复制代码
在测试类中调用一下这个学生类,看能否输出它父类的方法!
  1. public class Application {
  2.         public static void main(String[] args) {
  3.             Student student=new Student();
  4.             student.run();
  5.       }
  6.     }
复制代码
在java中所有的类都继承Object类
输出一下看是否调用Person中的run方法
  1. 人会奔跑
复制代码
可以用ctrl+h看一下结构

我们可以看到Person类继承于Object类,然后Studet
又继承Person类
super

​      super在java中两种用法

  • 在子类中调用父类的属性或方法
​      因为在java中子类没办法直接调用父类的方法或属性,如果想要调用,必须使用java关键字!
写个简单的代码实际体验一下java关键字
先定义Person类:
  1. public class Person {
  2.     protected String name="star";
  3. }
复制代码
然后定义一个学生类,让学生类继承这个类:
  1. public class Student extends Person{
  2.     public String name="lingstar";
  3.     public void test(String name){
  4.         System.out.println(name);
  5.         System.out.println(this.name);
  6.         System.out.println(super.name);
  7.     }
  8. }
复制代码
定义测试类,用来输出结果
  1. public class Application {
  2.         public static void main(String[] args) {
  3.             Student student=new Student();
  4.             student.test("星星");
  5.       }
  6.     }
复制代码
输出:
  1. 星星
  2. lingstar
  3. star
复制代码

  • 在子类中调用父类构造器
​      在Java中,子类是父类的派生类,它的实例化依赖于父类的实例化。所以它的任何一个构造函数都必须要初始化父类,Java就是super关键字调用父类构造方法,且调用父类的无参构造必须放在第一行!
person类:
  1. public class Person {
  2.     public Person(){
  3.         System.out.println("调用了person的无参构造");
  4.     }
  5. }
复制代码
student类:
  1. public class Student extends Person{
  2. public Student(){
  3.     System.out.println("调用了Student的无参构造");
  4. }
  5. }
复制代码
直接实例化student看一下,代码是怎样执行的!
  1. public class Application {
  2.         public static void main(String[] args) {
  3.             Student student=new Student();
  4.       }
  5.     }
复制代码
输出结果:
  1. 调用了person的无参构造
  2. 调用了Student的无参构造
复制代码
从结果可以看出,是先调用了父类的无参构造方法,再调用子类的无参构造。
也就相当于是
  1. public Student(){
  2.     super();
  3.     System.out.println("调用了Student的无参构造");
  4. }
  5. }
复制代码
在studen中是这样执行的。先调用父类的构造器,且super只能放在第一行,放在下面会报错!
super总结:
​                1.super调用父类的构造方法,必须在构造方法的第一个!
​                2.super必须只能出现在子类的方法或构造方法中!
​        3.super和this不能同事调用构造方法!
super与this的区别:
代表的对象不同前提条件构造方法this代表本身调用这个对象没继承也可以使用this()本类的构造super代表父类对象的应用只能在继承条件中使用super()父类的构造方法的重写

​       在子类中如果创建了一个与父类中相同名称、相同返回值类型、相同参数列表的方法,只是方法体中的实现不同,以实现不同于父类的功能,这种方式被称为方法重写(override),又称为方法覆盖。当父类中的方法无法满足子类需求或子类具有特有功能的时候,需要方法重写。
注意:重写都是方法的重写与属性无关
eg:
定义一个A类和B类,让A继承B类,里面有一个相同的方法,输出先看一下效果
  1. public class A extends B{
  2.     @Override//注解:有功能的注解
  3.     public void test(){
  4.         System.out.println("A=>test()");
  5.     }
  6. }
复制代码
  1. public class B {
  2.     public void test(){
  3.         System.out.println("B=>test()");
  4.     }
  5. }
复制代码
测试类:
  1. public class Application {
  2.         public static void main(String[] args) {
  3.             //方法的调用只跟左边,定义的数据类型有关
  4.             A a=new A();
  5.             //a.test调用的是A类的方法
  6.             a.test();
  7.             //父类的引用指向了A
  8.             B b=new A();
  9.             b.test();
  10.       }
  11.     }
复制代码
输出:
  1. A=>test()
  2. B=>test()
复制代码
我们把static去掉,看一下方法的重写
  1. public class A extends B{
  2.     @Override//注解:有功能的注解
  3.     public void test(){
  4.         System.out.println("A=>test()");
  5.     }
  6. }
复制代码
再运行看一下结果:
  1. A=>test()
  2. A=>test()
复制代码
因为静态方法(加 static)是类的方法,而非静态是对象的方法。
有static时,b调用了B类的方法,因为b是用B定义的。
没有static时,b调用的是对象的方法,而b是用A类new的。
重写小结

​     1.重写需要有继承关系,子类重写父类的方法
​         2.子类与父类的方法名必须相同,方法体不同
​         3.参数列表必须相同
​         4.修饰符的范围可以扩大
​         5.抛出的异常:范围可以被缩写,但不能扩大:ClassNotFoundException-->Exception(大)
​         6.重写快捷键AIL+INSERT:Override
为什么要重写?

​                因为有时父类的功能,子类不一定需要,或者不一定满足
多态

什么是多态?

多态就是同一个行为具有多个不同表现形式或形态的能力。多态只是方法的多态,属性没有多态!
多态存在的条件

​        1.继承关系,需要有父子类之间的联系
​        2.方法需要被重写
​                这些不能重写:
​                                static 方法,属于类,不属于示例
​                                fianl 常量
​                                private修饰
​        3.父类引用指向子类对象
代码实现

接下来通过代码来体会一下:
先写一个Person类,让他作为Student类的父类
  1. public class Person {
  2.     public void run(){
  3.         System.out.println("人会快速跑");
  4.     }
  5. }
复制代码
再写Student类,继承Person类,且在Student类中重写Person类的方法
  1. public class Student extends Person{
  2.     @Override
  3.     public void run() {
  4.         System.out.println("人也会慢跑");
  5.     }
  6. }
复制代码
然后再通过测试类来看一下
  1. public class Application {
  2.         public static void main(String[] args) {
  3.             //一个对象的实际类型是确定的
  4. //            new Student();
  5. //            new Person();
  6. //          可以指向的引用类型就不确定了:父类的引用指向子类
  7.             //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
  8.             //student能调用的方法都是自己的或者父类的
  9.             Student s1=new Student();
  10.             //Person虽然可以指向子类,但是不能调用子类独有的方法
  11.             Person s2=new Person();
  12.             Object s3=new Student();//如果子类重写了父类,调用子类,如果子类没有重写就调用父类
  13.             s2.run();
  14.             //如果我在子类Student中写一个方法,而用s2去调用是调用不出来的!
  15.             s1.run();
  16.       }
  17.     }
复制代码
输出:
  1. 人会快速跑
  2. 人也会慢跑
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

一给

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表