Java基础学习:10、封装和继承和super、方法重载、多态、动态绑定
封装:
1、概念:
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
2、意义:
只能通过规定的方法访问数据。
隐藏类的实例细节,方便修改和实现。
3、实现步骤:

public class Encapsulation {
  public static void main(String[] args) {
    Person person = new Person("张三", 200, 30000);
    System.out.println(person.message());
  }
}
class Person{
  public String name;
  private int age;
  private double salary;
  public Person() {
  }
// 构造方法可以破解封装,那么如果既要实用构造器又要封装呢?
// 将set写在构造器里面
  public Person(String name, int age, double salary) {
//    this.name = name;
//    this.age = age;
//    this.salary = salary;
    setName(name);
    setAge(age);
    setSalary(salary);
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    if (name.length() >=2 && name.length() <=6) {
      this.name = name;
    } else {
      this.name = "张三";
    }
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    if (age >= 1 && age <= 150) {
      this.age = age;
    } else {
      System.out.println("输入的年龄不对,需要在1~150之间");
      this.age = 16;   // 给一个默认的年龄
    }
  }
  public double getSalary() {
    return salary;
  }
  public void setSalary(double salary) {
    this.salary = salary;
  }
  public String message() {
    return "姓名为:" + name + " " + "年龄为:"  + age + " " + "工资为:" + salary;
  }
}
继承:
1、定义:继承是类与类的一种关系,是一种“is a”的关系。比如“狗”继承“动物”,这里动物类是狗类的父类或者基类,狗类是动物类的子类或者派生类。
2、继承意义:
子类拥有父类的所有属性和方法(除了private修饰的属性不能拥有)从而实现了实现代码的复用。
3、语法规则:只要在子类加上extends关键字继承相应的父类就可以了。


4、注意点:
a、子类继承了父类所有的属性和方法,非私有的属性和方法可以在子类直接访问,
但是私有的属性和方法不能再子类直接访问,要通过父类提供的公共方法区访问。
public class Student {
  public int score1 = 100;
  public int score2 = 80;
  private int score3 = 90;
  // 父亲提供一个public方法,返回score3
  public int getScore3() {
    return score3;
  }
  public void test1() {
    System.out.println("学生正在考试数学");
  }
  public void test2() {
    System.out.println("学生正在考试英语");
  }
  private void test3() {
    System.out.println("学生正在考试语文");
  }
  // 父亲提供一个public方法,调用test03
  public void callTest() {
    test3();
  }
}
b、子类必须调用父类的构造器,完成父类的初始化。
c、当创建子类对象时,不管使用子类哪个构造器,默认情况都会去调用父类的无参构造器。
如果父类没有提供无参构造器,则必须在子类的构造器中用supre去指定使用父类的哪个构造器完成对父类的初始化工作,否则编译 不会通过。
d、如果希望指定去调用父类的某个构造器,则需要显示的调用一下:super(参数列表);
e、super在使用时,必须放在构造器第一行(super只能在构造器中使用)。
f、super()和this()都只能放在构造器第一行,因此两个方法不能共存在一个构造器中。
g、Java中所有类都是object类的子类。
h、父类构造器的调用不限于直接父类,将一直往上追溯到object类(顶级父类)。
i、子类最多只能继承一个父类,即Java中的单继承机制。如果要让A继承B类和C类呢?【A继承B,B继承C】。
j、不能滥用继承,子类和父类必须满足is-a的逻辑关系:如 猫是动物。
继承内存图:

继承中this和super:
public class ExtendsHomeWork {
  public static void main(String[] args) {
    C c = new C();
  }
}

super关键字:
1、定义:super代表父类的引用,用于访问父类的属性、方法、构造器。
2、基本用法:
a、用于访问父类的属性,但不能访问父类的private属性:super.属性名;
b、用于访问父类的方法,但不能访问父类private方法:super.方法名(参数列表);
c、访问父类的构造器:super(参数列表); 只可以放在构造器第一句,只能出现一句。
3、意义及细节:
a、super调用父类构造器的意义(分工明确,父类的属性由父类初始化,子类的属性由子类初始化)。
class NotePad extends Computer {
  private String color;
  public NotePad(String cpu, int memory, int disk, String color) {
    super(cpu, memory, disk);
    this.color = color;
  }
}
b、当子类和父类中的成员(属性和方法)重名时,为了访问父类成员,必须通过super,如果没有重名,则super、this以及直接访问都是一样的。
在子类中使用:直接访问、this、super三者的区别:
直接访问和this:
1、先找本类,本类有,则调用。
2、本类没有,找父类(如果有且可以调用,则调用;如果有但是不能调用,则报错)。
3、如果父类没有,则继续往上找,直到object类。一直没有找到,提示不存在。
super:
1、直接找父类,不找本类。其余规则如上。
class Computer {
  private String cpu;
  private int memory;
  private int disk;
  public int num = 12;
  public Computer(String cpu, int memory, int disk) {
    this.cpu = cpu;
    this.memory = memory;
    this.disk = disk;
  }
}
class NotePad extends Computer {
  private String color;
  public int num = 1;
  public void test() {
    System.out.println(num);        // 1
    System.out.println(this.num);   // 1
    System.out.println(super.num);  // 12
  }
}
c、super访问不限于直接父类,如果爷爷类也有同名成员,也可以使用super去访问。如果多个上级类都有同名成员,遵循就近原则。

继承方法重写:
1、定义:方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么就是子类方法覆盖了父类方法。
2、满足条件:
a、子类的方法的形参列表、方法名称要和父类的参数方法名称完全一样。
b、子类方法的返回类型要和父类一样活着是父类返回类型的子类:如父类返回类型是object,子类是String。
c、子类方法不可以缩小父类方法的访问权限:public > protected > 默认 > private。
方法重写和方法重载的区别:
1、方法重载:Java中允许在同一个类中,多个同名方法的存在,到要求形参列表不一致。
2、方法重写:子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么就是子类方法覆盖了父类方法。

多态:
一、多态概述:
1、多态是继封装、继承之后,面向对象的第三大特性。
2、多态现实意义理解:
现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。
Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。
3.多态体现为父类引用变量可以指向子类对象。
Animal animal = new Dog("米奇", 23);
4.前提条件:必须有子父类继承关系。
注意:在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。
// 运行时,执行到该行的时候,animal运行类型是dog,所以是dog的eat();
animal.eat(); // 小狗吃东西
5.多态的定义与使用格式
定义格式:父类类型 变量名=new 子类类型();
6.理解:
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
二、多态成员特点:
1、成员属性(变量):
属性没有重写之说,属性的值看编译类型:直接调用的就是animal的属性的值:
Animal animal = new Dog("米奇", 23);   // 编译类型是animal
System.out.println(animal.num); // 父类的num
2、成员方法:
成员方法有重写,如果重写,调用的就是子类方法,无重写,调用父类:
animal.say(); // 子类重写父类say方法,调用的是子类
  public static void main(String[] args) {
    // animal 编译类型是 Animal,运行类型是 dog
    Animal animal = new Dog("米奇", 23);
    // 运行时,执行到该行的时候,animal运行类型是dog,所以是dog的eat();
  // 如果子类没有重写父类的方法,那么调用的就是父类的方法
    animal.AnimalEat();  // 父类的方法:动物吃东西
  // 如果子类重写了父类的方法,那么调用的就是子类的方法。
   animal.say();  // 子类的方法:小狗唱歌
    System.out.println(animal.num);  // 父类的值:10
  }
三、多态的转型 :向上转型和向下转型
1、向上转型:
  父类的引用指向了子类的对象(多态本身就是向上转型过的过程)
            使用格式:父类类型 变量名=new 子类类型();
Animal animal = new Dog("米奇", 23);
特点:
a、可以调用父类的所有成员(变量和方法),但是需要遵循访问权限。
b、不能调用子类的特有成员,可以调用子类的重写方法:因为在编译阶段,能调用哪些成员,有编译类型决定(编译看左边)。
为什么不能调用子类成员?
因为编译的时候就不通过,编译就会报错。
总结:向上转型 父类类型 变量名=new 子类类型();
a、编译的时候只能调用父类方法。
Animal animal = new Dog("米奇", 23);
animal.AnimalEat(); // 父类方法
animal.DogEat(); // 子类方法报错
b、运行的时候还是先从子类找该方法,如果有就调用,没有往上找。
(就是如果子类重写了父类方法,运行的时候就会调用子类,没有重写就不会调用子类方法,调用父类方法)
// 子类重写了父类say方法:编译时调用的是父类方法,但是实际运行时调用的是子类重写的say方法
animal.say(); // 小狗唱歌
2、向下转型:
1、前提:如果要向下转型必须先向上转型:
Animal animal = new Dog;
2、语法:子类类型 引用名 = (子类类型) 父类引用;
Dog dog = (Dog) animal;
3、注意点:
a、只能强转父类引用,不能强转父类对象。
Dog dog = (Dog) Animal; // 错误
b、向下转型后,可以调用子类中所有成员。
dog.DogEat();
instanceof:比较操作符
1、意义:
1、用于判断对象的运行类型是否为某个类型 或者 为某类型的子类型。
2、它的作用是测试它左边的对象是否是它右边的类的实例
public class instanceOf {
  public static void main(String[] args) {
    BB bb = new BB();
    System.out.println(bb instanceof BB);  // true
    System.out.println(bb instanceof AA);  // true
    // aa的编译类型是AA,aa的运行类型是BB
    AA aa = new BB();
    // 下面这句话意思:aa的运行类型BB 是 AA 的类或者子类吗?
    System.out.println(aa instanceof AA);  // true
    // 下面这句话意思:aa的运行类型BB 是 BB 的类或者子类吗?
    System.out.println(aa instanceof BB);  // true
  }
}
class AA {}
class BB extends AA{}
2、实际用法:

在写程序的时候,如果要进行类型转换,我们最好使用instanceof运算符来判断
它左边的对象是否是它右边的类的实例,再进行强制转换。
动态绑定:
1、当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定。
public class DynamicBinding {
  public static void main(String[] args) {
    // father的编译类型:Father;father的运行类型:Son。
    Father father = new Son();
    // 调用方法时,会和运行类型绑定,cal方法会调用子类的sum方法。
    System.out.println(father.cal());  // 40
  }
}
class Father{
  int num = 10;
  public int cal() {
    return sum() + 20;
  }
  public int sum() {
    return num + 10;
  }
}
class Son extends Father{
  int num = 20;
  public int sum() {
    return num;
  }
  public int cal() {
    return num + 20;
  }
}
2、当调用对象属性的时候,没有动态绑定,哪里声明,哪里使用。
多态参数:
方法的形参类型为父类类型,实参为子类类型:
public class Main {
  public static void main(String[] args) {
    Ordinary tom = new Ordinary("tom", 2500);
    Manager milan = new Manager("milan", 5000, 200000);
    Main main = new Main();
    main.showEmpAnnual(tom);
    main.showEmpAnnual(milan);
    main.testWork(tom);
    main.testWork(milan);
  }
  // 方法:输出普通员工和经理的工资
  public void showEmpAnnual(Employee e) {
    System.out.println(e.getAnnual());
  }
  // 添加一个方法:如果是普通员工,则调用work方法,如果是经理,则调用manage方法
  // 使用 类型判断 + 向下转型   这里 e 就是 Employee的引用类型 Employee e =
  public void testWork(Employee e) {
    if (e instanceof Ordinary) {
      /*
      下面这句相当于:
      Ordinary ordinary = (Ordinary)e;
      ordinary.work;
      的简写
       * */
      ((Ordinary) e).work();  // 向下转型
    } else if (e instanceof Manager) {
      ((Manager) e).manage();
    } else {
      System.out.println("不处理");
    }
  }
}
toString方法:
1、他是object类下面的一个方法,因此所有的类都可以使用。
2、默认返回:全类名(包名 + 类名)+ @ + 十六进制哈希值。
3、当直接输出一个对象时,默认会调用tostring方法。
public class ToString {
  public static void main(String[] args) {
    AA aa = new AA();
    System.out.println(aa.toString());  // com.homework.AA@776ec8df
    System.out.println(aa);  // com.homework.AA@776ec8df
  }
}
class AA {}
4、子类往往会重写tostring方法,用于返回对象的属性信息
public class ToString {
  public static void main(String[] args) {
    AA aa = new AA("mary", 23);
    System.out.println(aa.toString());  // AA{name='mary', age=23}
    System.out.println(aa);  // AA{name='mary', age=23}
  }
}
class AA {
  String name;
  int age;
  public AA(String name, int age) {
    this.name = name;
    this.age = age;
  }
  @Override
  public String toString() {
    return "AA{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
  }
}
Java基础学习:10、封装和继承和super、方法重载、多态、动态绑定的更多相关文章
- java基础学习笔记二(接口、super、this)
		
一.super 和 this的用法 主要解释一下引用构造函数的用法 super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句) this(参数):调用本类中另一种形式的构造函数(应 ...
 - Java基础学习篇---------封装
		
一.类和对象分配内存 二.Java中的内部类 : 可以直接去访问外部类的所有属性(包括私有成员) 1.Java中成员内部类 (1).内部类的方法可以直接访问外部类的类中的所有成员变量 (2).外部类 ...
 - java===java基础学习(11)---继承
		
继承可以解决代码复用,让编程更加靠近人的思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法.所有的子类不需要重新定义这些属性和方法,只需要通过ex ...
 - java基础学习笔记六(继承)
		
继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父 ...
 - java基础学习之"堆" "栈" "静态存储区" "方法区"
		
引用部分 java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来) Java堆.栈和常量池以及相关String的讲解 等我看完"深入理 ...
 - Java基础学习-- 继承 的简单总结
		
代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...
 - 尚学堂JAVA基础学习笔记
		
目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...
 - [转帖]java基础学习总结——多态(动态绑定)
		
https://www.cnblogs.com/xdp-gacl/p/3644035.html 多态的概念 java基础学习总结——多态(动态绑定) 一.面向对象最核心的机制——动态绑定,也叫多态
 - Java基础学习(2)
		
Java基础学习(二) 面向对象 对象:客观存在的事物 面向对象:人具体关注的事物的某些信息 类:是模子,确定对象会拥有的特征(属性)和行为(方法) 对象的属性:对象具有的各种特征 对象的方法:对象能 ...
 - java基础学习笔记五(抽象类)
		
java基础学习总结——抽象类 抽象类介绍
 
随机推荐
- Vue的指令(内容渲染、属性绑定、javaScript表达式、事件绑定、事务对象、双向绑定、逻辑<if-show-for>)
			
VUE指令 内容渲染指令 v-text v-html v-text="message" v-text会覆盖默认的值 {{message+"!"}}插值表达式 差 ...
 - day14-异常处理
			
异常处理 1.基本介绍 SpringMVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler映射.数据绑定以及目标方法执行时发生的异常 有两种方案来进行异常 ...
 - 快学会这个技能-.NET API拦截技法
			
大家好,我是沙漠尽头的狼. 本文先抛出以下问题,请在文中寻找答案,可在评论区回答: 什么是API拦截? 一个方法被很多地方调用,怎么在不修改这个方法源码情况下,记录这个方法调用的前后时间? 同2,不修 ...
 - aspnetcore 原生 DI 实现基于 key 的服务获取
			
你可能想通过一个字符串或者其他的类型来获取一个具体的服务实现,那么在 aspnetcore 原生的 MSDI 中,如何实现呢?本文将介绍如何通过自定义工厂来实现. 我们现在恰好有基于 Json 和 M ...
 - C端自动化实现:appium+winappdriver+python
			
一. 前言 有小伙伴有办公自动化的需求,特此出一篇C端自动化教程,并附带demo案例.C端的自动化比B端多一个appium,其他的操作大同小异. 二. 环境 appium:exe工具,用于启动服务,官 ...
 - kubernetes之Ingress发布Dashboard(二)
			
1.什么是Dashboard Dashboard 是基于网页的 Kubernetes 用户界面. 你可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错, ...
 - KingbaseES DBLink 介绍
			
DBLink 扩展插件功能与 Kingbase_FDW 类似,用于远程访问KingbaseES 数据库.相比于Kingbase_FDW,DBLink 功能更强大,可以执行DML,还可以通过 begin ...
 - pat 乙级1024 科学计数法关于stl中size()的一些思考即测试点六,无符号整数问题
			
来,先看题目:1024 科学计数法 分数 20 作者 HOU, Qiming 单位 浙江大学 科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9 ...
 - 解决用flex布局时内容溢出的问题
			
1,2正常现象如下: 2,点击折叠图标 再点折叠 无图标了 解决:flex:1,width:0 就可以了
 - ubuntu系统的虚机 迁移到大厂的云服务器 后发现 实例内网一直都是原虚机的内网IP,
			
ubuntu SMC迁移 后发现 实例内网一直都是原虚机的内网IPip a能看到现在的ECS内网以及原虚机的内网 但是ifconfig看只有原虚机的内网IP于是 尝试dhclient eth0重启内网 ...