• Java笔记七(封装,继承与多态)


    封装

    该露的露,该藏的藏

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

    封装(数据的隐藏)

    通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问

    属性私有

    1. package com.oop.demo04;
    2. //类 private:私有
    3. public class Student {
    4. //属性私有
    5. private String name; //名字
    6. private int id; //学号
    7. private char sex; //性别
    1. package com.oop.demo04;
    2. public class Application {
    3. public static void main(String[] args) {
    4. Student s1=new Student();
    5. s1.name//错误代码
    6. }
    7. }

    此时如果直接调用s1.name则会报错,因为属性私有

    正确方法:

    1. package com.oop.demo04;
    2. //类 private:私有
    3. public class Student {
    4. //属性私有
    5. private String name; //名字
    6. private int id; //学号
    7. private char sex; //性别
    8. //提供一些可以操作这个属性的方法
    9. //提供一些public的get.set方法
    10. //get获得这个数据
    11. public String getName(){
    12. return this.name;
    13. }
    14. //set给这个数据设置值
    15. public void setName(String name){
    16. this.name=name;
    17. }
    18. }
    1. package com.oop.demo04;
    2. public class Application {
    3. public static void main(String[] args) {
    4. Student s1=new Student();
    5. s1.setName("佳伟");
    6. System.out.println(s1.getName());
    7. }
    8. }

    快捷键alt+ins快速生成get和set方法

    对用户的输入进行限制,以年龄为例:

    1. package com.oop.demo04;
    2. //类 private:私有
    3. public class Student {
    4. //属性私有
    5. private String name; //名字
    6. private int id; //学号
    7. private char sex;//性别
    8. private int age;
    9. //提供一些可以操作这个属性的方法
    10. //提供一些public的get.set方法
    11. //get获得这个数据
    12. public String getName(){
    13. return this.name;
    14. }
    15. public int getAge() {
    16. return age;
    17. }
    18. public void setAge(int age) {//对输入不合法的年龄进行限制
    19. if (age>120||age<0){
    20. this.age=3;
    21. }else {
    22. this.age=age;
    23. }
    24. }
    25. //set给这个数据设置值
    26. public void setName(String name){
    27. this.name=name;
    28. }
    29. }
    1. package com.oop.demo04;
    2. public class Application {
    3. public static void main(String[] args) {
    4. Student s1=new Student();
    5. s1.setName("佳伟");
    6. System.out.println(s1.getName());
    7. s1.setAge(999);
    8. System.out.println(s1.getAge());
    9. }
    10. }

    此时年龄便会输出不合法

    封装的意义:

    1.提高程序的安全性,保护数据

    2.隐藏代码的实现细节

    3.统一接口

    4.系统可维护性

    继承

    继承的本质是对某一批类的抽象

    extends的意思是“扩展”。子类是父类的扩展

    JAVA中类只有单继承,没有多继承

    继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。

    假设Person是父类,Student与Teacher是子类

    则可这样写

    1. package com.oop.demo05;
    2. public class Person {
    3. }
    1. package com.oop.demo05;
    2. public class Student extends Person {
    3. }
    1. package com.oop.demo05;
    2. public class Teacher extends Person {
    3. }

    子类继承父类,就会拥有父类的全部方法

    1. package com.oop.demo05;
    2. public class Person {
    3. public void say(){
    4. System.out.println("说了一句话");
    5. }
    6. }
    1. package com.oop.demo05;
    2. public class Application {
    3. public static void main(String[] args) {
    4. Student student=new Student();
    5. student.say();
    6. }
    7. }

    但是拥有父类的所有方法不代表可以使用父类的所有方法,例如使用封装的关键词private

    1. package com.oop.demo05;
    2. public class Person {
    3. private int money=10_0000_0000;
    4. public void say() {
    5. System.out.println("说了一句话");
    6. }
    7. public int getMoney(){
    8. return money;
    9. }
    10. public void setMoney(int money){
    11. this.money=money;
    12. }
    13. }

    则子类需使用父类设置的方法使用

    1. package com.oop.demo05;
    2. public class Application {
    3. public static void main(String[] args) {
    4. Student student=new Student();
    5. student.say();
    6. System.out.println(student.getMoney());
    7. }
    8. }

    IDEA快捷键:

    ctrl+H:查看程序树

    super

    调用父类,如下

    1. package com.oop.demo05;
    2. public class Student extends Person {
    3. private String name="jiawei";
    4. public void print(){
    5. System.out.println("Student");
    6. }
    7. public void test(String name){
    8. System.out.println(name);
    9. System.out.println(this.name);
    10. System.out.println(super.name);//调用父类
    11. }
    12. }
    1. package com.oop.demo05;
    2. public class Person {
    3. protected String name="weiwei";
    4. public void print(){
    5. System.out.println("Person");
    6. }
    7. }
    1. package com.oop.demo05;
    2. import com.oop.demo05.Person;
    3. import com.oop.demo05.Student;
    4. public class Application {
    5. public static void main(String[] args) {
    6. Student student=new Student();
    7. student.test("佳伟");
    8. }
    9. }

    运行结果如下

    调用父类方法:

    1. package com.oop.demo05;
    2. public class Person {
    3. protected String name="weiwei";
    4. public void print(){
    5. System.out.println("Person");
    6. }
    7. }
    1. package com.oop.demo05;
    2. public class Student extends Person {
    3. private String name="jiawei";
    4. public void print(){
    5. System.out.println("Student");
    6. }
    7. public void test1(){
    8. print();//当前类
    9. this.print();//当前类
    10. super.print();//调用父类
    11. }
    12. public void test(String name){
    13. System.out.println(name);
    14. System.out.println(this.name);
    15. System.out.println(super.name);//调用父类
    16. }
    17. }
    1. package com.oop.demo05;
    2. import com.oop.demo05.Person;
    3. import com.oop.demo05.Student;
    4. public class Application {
    5. public static void main(String[] args) {
    6. Student student=new Student();
    7. //student.test("佳伟");
    8. student.test1();
    9. }
    10. }

    运行结果如下

    私有的东西同样无法被继承

    注意调用父类的构造器必须放在子类构造器的第一行

    super注意点

    1.super调用父类的构造方法,必须在构造方法的第一个

    2.super必须只能出现在子类的方 法或者构造方法中

    3.super和this不能同时调用构造方法

    与this对比

    代表的对象不同

    this:本身调用者这个对象

    super:代表父类对象的应用

    前提

    this:没有继承也可以使用

    super:只能在继承条件才可以使用

    this():本类的构造

    super():父类的构造

    方法的重写

    静态方法:

    1. package com.oop.demo05;
    2. public class A extends B{
    3. public static void test() {
    4. System.out.println("A=>test()");
    5. }
    6. }
    1. package com.oop.demo05;
    2. public class A extends B{
    3. public static void test() {
    4. System.out.println("A=>test()");
    5. }
    6. }
    1. package com.oop.demo05;
    2. import com.oop.demo05.A;
    3. import com.oop.demo05.B;
    4. public class Application {
    5. public static void main(String[] args) {
    6. //方法的调用只和左边,定义的数据类型有关
    7. A a=new A();
    8. a.test();
    9. //父类的引用指向了子类
    10. B b=new A();
    11. b.test();
    12. }
    13. }

    运行结果如下:

    可以发现方法的调用只和左边,定义的数据类型有关

    非静态方法的重写:

    A与B同时去掉static

    1. package com.oop.demo05;
    2. public class B {
    3. public void test() {
    4. System.out.println("B=>test()");
    5. }
    6. }
    1. package com.oop.demo05;
    2. public class A extends B{
    3. public void test() {
    4. System.out.println("A=>test()");
    5. }
    6. }
    1. package com.oop.demo05;
    2. import com.oop.demo05.A;
    3. import com.oop.demo05.B;
    4. public class Application {
    5. public static void main(String[] args) {
    6. //方法的调用只和左边,定义的数据类型有关
    7. A a=new A();
    8. a.test();
    9. //父类的引用指向了子类
    10. B b=new A();//子类重写了父类的方法
    11. b.test();
    12. }
    13. }

    运行结果如下

    alt+ins快捷键:快速重写方法

    静态的方法与非静态的方法区别很大

    此时子类才重写了父类的方法,才算重写

    重写的关键词只能是public

    重写:需要有继承关系,子类重写父类的方法!

    1.方法名必须相同

    2.参数列表必须相同

    3.修饰符:范围可以扩大:public>Protected>Default>private

    4.抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException——>Exception(大)

    重写,子类的方法和父类必要一致;方法体不同!

    为什么需要重写:

    父类的功能,子类不一定需要或者不一定满足

    多态

    1. package com.oop.demo06;
    2. public class Application {
    3. public static void main(String[] args) {
    4. //一个对象的实际类型是确定的
    5. //new Student();
    6. //new Person();
    7. //可以指向的引用类型就不确定了
    8. //Student能调用的方法都是自己的或者继承父类的
    9. Student s1=new Student();
    10. //Person父类型,可以指向子类,但是不难调用子类独有的方法
    11. Person s2=new Student();//父类的引用指向子类
    12. //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
    13. s2.run();//子类重写了父类的方法,执行子类的方法
    14. s1.eat();
    15. }
    16. }

    .

    1. package com.oop.demo06;
    2. public class Student extends Person {
    3. @Override
    4. public void run() {
    5. System.out.println("son");
    6. }
    7. public void eat(){
    8. System.out.println("eat");
    9. }
    10. }
    1. package com.oop.demo06;
    2. public class Person {
    3. public void run(){
    4. System.out.println("run");
    5. }
    6. }

    运行结果:

    子类能调用的方法都是自己的或者继承父类的

    父类型可以指向子类,但是不能调用子类独有的方法

    可以强制类型转换把s2从父类转换成子类

    ((Student)s2).eat();

    多态注意事项:

    1.多态是方法的多态,属性没有多态

    2.父类和子类有联系 否则有类型转换异常 ClassCastException

    2.存在条件:继承关系,方法需要重写,父类引用指向子类对象

    不能重写的关键词:

    1.static 方法,属于类,它不属于实例

    2.final 常量

    2.private方法

  • 相关阅读:
    golang promethus consul 服务发现
    使用 Python进行量化交易:前向验证分析
    mybatis入门
    阿里云服务器u1和经济型e系列性能差异?哪个比较好?
    Logback日志配置
    基于对立非洲秃鹫优化算法求解单目标优化问题(OAVOA)含Matlab代码
    week 6 贪心
    2024年新版宝塔面板如何安装WordPress网站教程
    TDengine概述以及架构模型
    同花顺_代码解析_技术指标_C
  • 原文地址:https://blog.csdn.net/m0_73770225/article/details/133593107