Java learning_Day4(下)

本人学习视频用的是马士兵的,也在这里献上

<链接:https://pan.baidu.com/s/1qKNGJNh0GgvlJnitTJGqgA>

提取码:fobs

内容

  • Object 类
  • 对象转型(casting)
  • 动态绑定和多态(polymorphism)
  • 抽象类

Object 类

  • Object类是所有Java类的根基类
  • 如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类

  1. public class Person {
  2. ...
  3. }

等价于

  1. public class Person extends Object {
  2. ...
  3. }

toString() 方法

  • Object 类中有定义 public String toString() 方法,其返回值是 String 类型,描述当前对象的有关信息。
  • 在进行String与其他类型数据的连接操作时(如:System.out.println("info" + person)),将自动调用该对象类的 toString()方法。
  • 可以根据需要在用户自定义类型中重写 toString() 方法。

equals 方法

  • public boolean equals(Object obj) 方法,提供定义对象是否"相等"的逻辑。
  • Object 的 equals. 方法定义为: x.equals(y) 当 x 和 y 是哦、同一个对象的引用时返回 true 否则返回 false
  • JDK提供的一些类,如String,Date等,重写了Object的equals方法,调用这些类的equals方法, x.equals(y),当 x 和 y 所引用的对象是同一类对象且属性内容相等时(并不一定是相同对象),返回 true 否则返回 false。
  • 可以根据需要在用户自定义类型中重写 equals 方法。

对象转型(casting)

  • 一个基类的引用类型变量可以“指向”其子类的对象。
  • 一个基类的引用不可以访问其子类对象新增加的成员(属性和方法)。
  • 可以使用引用变量 instanceof 类名来判断该引用型变量所“指向”的对象是否属于该类或该类的子类。
  • 子类的对象可以当作基类的对象来使用称作向上转型(upcasting),反之称为向下转型(downcasting)。

以下面程序为例

  1. class Animal {
  2. public String name;
  3. Animal(String name) {
  4. this.name = name;
  5. }
  6. }
  7. class Cat extends Animal {
  8. public String eyesColor;
  9. Cat(String name, String color) {
  10. super(name);
  11. eyesColor = color;
  12. }
  13. }
  14. class Dog extends Animal {
  15. public String furColor;
  16. Dog(String name, String color) {
  17. super(name);
  18. furColor = color;
  19. }
  20. }
  21. public class TestCasting {
  22. public static void main(String[] args) {
  23. Animal a = new Animal("name");
  24. Cat c = new Cat("cat name", "blue");
  25. Dog d = new Dog("dog name", "black");
  26. System.out.println(a instanceof Animal); //true
  27. System.out.println(c instanceof Animal); //true
  28. System.out.println(d instanceof Animal); //true
  29. System.out.println(a instanceof Cat); //false
  30. Animal a1 = new Dog("dog name", "yellow"); //向上转型
  31. System.out.println(a1.name ); //true
  32. System.out.println(a1 instanceof Animal); //true
  33. System.out.println(a1 instanceof Dog); //true
  34. Animal a2 = new Animal("name");
  35. Dog d1 = (Dog)a2; //向下转型,!error
  36. a2 = new Dog("dog name", "yellow");
  37. System.out.println(d1.furColor);
  38. }
  39. }

输出结果

  1. true
  2. true
  3. true
  4. false
  5. dog name
  6. true
  7. true
  8. Exception in thread "main" java.lang.ClassCastException: class Animal cannot be cast to class Dog (Animal and Dog are in unnamed module of loader 'app')

对程序段进行分析

程序段 Animal a1 = new Dog("dog name", "yellow"); 即是向上转型,将父类对象 Animal 转换成子类对象 Dog。转型成功,编译器顺利执行。

而在程序段

  1. Animal a2 = new Animal("name");
  2. Dog d1 = (Dog)a2; //向下转型,!error
  3. a2 = new Dog("dog name", "yellow");
  4. System.out.println(d1.furColor);

此处即是向下转型,在语句 Dog d1 = (Dog)a2; 中,父类对象 Animal 无法直接转换为子类对象 Dog。因为此时 父类对象 Animal 还没有完全拥有子类对象 Dog 的所有属性,必须改为:

  1. Animal a2 = new Animal("name");
  2. a2 = new Dog("dog name", "yellow");
  3. Dog d1 = (Dog)a2; //必须强制转换
  4. System.out.println(d1.furColor); //yellow

此时,向下转型才能编译成功。

动态绑定和多态(polymorphism)

  • 动态绑定是指在执行期间(而非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
  • 动态绑定的条件:
    1. 要有继承
    2. 子类重写父类方法
    3. 父类引用指向子类对象

以下面程序为例

  1. class Animal {
  2. private String name;
  3. Animal(String name) {
  4. this.name = name;
  5. }
  6. public void enjoy(){
  7. System.out.println("叫声......");
  8. }
  9. }
  10. class Cat extends Animal {
  11. private String eyesColor;
  12. Cat(String n,String c) {
  13. super(n);
  14. eyesColor = c;
  15. }
  16. public void enjoy() {
  17. System.out.println("猫叫声......");
  18. }
  19. }
  20. class Dog extends Animal {
  21. private String furColor;
  22. Dog(String n,String c) {
  23. super(n);
  24. furColor = c;
  25. }
  26. public void enjoy() {
  27. System.out.println("狗叫声......");
  28. }
  29. }
  30. class Lady {
  31. private String name;
  32. private Animal pet;
  33. Lady(String name, Animal pet) {
  34. this.name = name;
  35. this.pet = pet;
  36. }
  37. public void myPetEnjoy(){
  38. pet.enjoy();
  39. }
  40. }
  41. public class TestPoly {
  42. public static void main(String args[]){
  43. Cat c = new Cat("catname","blue");
  44. Dog d = new Dog("dogname","black");
  45. Lady l1 = new Lady("l1",c);
  46. Lady l2 = new Lady("l2",d);
  47. l1.myPetEnjoy();
  48. l2.myPetEnjoy();
  49. }
  50. }

输出

  1. 猫叫声......
  2. 狗叫声......

在上述程序中,程序段

  1. Lady(String name, Animal pet) {
  2. this.name = name;
  3. this.pet = pet;
  4. }

说明Lady类对象拥有类型为 Animal 的 pet,但是输出结果不是 Animal的方法 "叫声......",而是分别输出了其子类对象的方法,这其实就是多态机制的一种体现,在程序执行期间,Lady l1 对象拥有的 pet 为 Cat,因而调用 Cat 的方法;Lady l2 对象拥有的 pet 为 Dog,因而调用 Dog 的方法。

抽象类

  • abstract 关键字来修饰一个类时,这个类叫做抽象类;用 abstract 来修饰一个方法时,该方法叫做抽象方法。
  • 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
  • 抽象类不能被实例化。
  • 抽象方法只需要声明,不需要实现。

以下面程序为例

  1. abstract class Animal {
  2. private String name;
  3. Animal(String name) {
  4. this.name = name;
  5. }
  6. public abstract void enjoy();
  7. }
  8. class Cat extends Animal {
  9. private String eyesColor;
  10. Cat(String n,String c) {
  11. super(n);
  12. eyesColor = c;
  13. }
  14. public void enjoy() {
  15. System.out.println("猫叫声......");
  16. }
  17. }
  18. class Dog extends Animal {
  19. private String furColor;
  20. Dog(String n,String c) {
  21. super(n);
  22. furColor = c;
  23. }
  24. public void enjoy() {
  25. System.out.println("狗叫声......");
  26. }
  27. }
  28. class Lady {
  29. private String name;
  30. private Animal pet;
  31. Lady(String name,Animal pet) {
  32. this.name = name;
  33. this.pet = pet;
  34. }
  35. public void myPetEnjoy() {
  36. pet.enjoy();
  37. }
  38. }
  39. public class TestAbstract {
  40. public static void main(String args[]){
  41. Cat c = new Cat("catname","blue");
  42. Dog d = new Dog("dogname","black");
  43. Lady l1 = new Lady("l1",c);
  44. Lady l2 = new Lady("l2",d);
  45. l1.myPetEnjoy();
  46. l2.myPetEnjoy();
  47. }
  48. }

父类 Animal 没有去实现 enjoy 方法,而是选择将其声明为 abstract 方法,同时将类本身修饰为 abstract 类,让其子类实现它的方法。

参考资料

Java转型(向上或向下转型)|CSDN

https://blog.csdn.net/shanghui815/article/details/6088588

Java_Day4(下)的更多相关文章

  1. JavaDay3(上)

    Java learning_Day3(上) 本人学习视频用的是马士兵的,也在这里献上 <链接:https://pan.baidu.com/s/1qKNGJNh0GgvlJnitTJGqgA> ...

  2. C++程序结构---1

    C++ 基础教程Beta 版 原作:Juan Soulié 翻译:Jing Xu (aqua) 英文原版 本教程根据Juan Soulie的英文版C++教程翻译并改编. 本版为最新校对版,尚未定稿.如 ...

  3. Android SwipeRefreshLayout 下拉刷新——Hi_博客 Android App 开发笔记

    以前写下拉刷新 感觉好费劲,要判断ListView是否滚到顶部,还要加载头布局,还要控制 头布局的状态,等等一大堆.感觉麻烦死了.今天学习了SwipeRefreshLayout 的用法,来分享一下,有 ...

  4. IE6、7下html标签间存在空白符,导致渲染后占用多余空白位置的原因及解决方法

    直接上图:原因:该div包含的内容是靠后台进行print操作,输出的.如果没有输出任何内容,浏览器会默认给该空白区域添加空白符.在IE6.7下,浏览器解析渲染时,会认为空白符也是占位置的,默认其具有字 ...

  5. Ubuntu下使用nvm

    写在前面:刚写着写着博客就跨年了,希望新的一年大家万事如意,一切向"前"看! 安装 wget -qO- https://raw.githubusercontent.com/crea ...

  6. Cmder--Windows下命令行利器

    cmder cmder是一个增强型命令行工具,不仅可以使用windows下的所有命令,更爽的是可以使用linux的命令,shell命令. 安装包 安装包链接 下载后,直接解压即用. 修改命令提示符λ为 ...

  7. NodeJs在Linux下使用的各种问题

    环境:ubuntu16.04 ubuntu中安装NodeJs 通过apt-get命令安装后发现只能使用nodejs,而没有node命令 如果想避免这种情况请看下面连接的这种安装方式: 拓展见:Linu ...

  8. GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级

    一.使用Raw文件夹下的数据库文件 在使用GreenDao框架时,数据库和数据表都是根据生成的框架代码来自动创建的,从生成的DaoMaster中的OpenHelper类可以看出: public sta ...

  9. [APUE]UNIX进程的环境(下)

    一.共享库 共享库使得可执行文件中不再需要包含常用的库函数,而只需在所有进程都可存取的存储区中保存这种库例程的一个副本.程序第一次执行的时候或第一次调用某个库函数的时候,用动态链接方法将程序与共享库函 ...

随机推荐

  1. React中setState注意事项

    setState是一个异步函数,异步获取数据 学习react在使用ref和setState操作DOM时会遇到的问题: ref获取ul结点元素 错误写法:得到的ul长度总是上一次输入后的长度 结果: 正 ...

  2. 在Kali linux下使用docker配置sqli-labs(国内源的配置和系统软件更新)

    本篇blog导航: ~前言 ~第一步:在安装好的kali配置国内源 ~第二步:安装docker ~第三步:docker下安装sqli-labs ~写在最后. 前言: 最近闲来无事,在闯关sqli-la ...

  3. Go语言基础之接口(面向对象编程下)

    1 接口 1.1 接口介绍 接口(interface)是Go语言中核心部分,Go语言提供面向接口编程,那么接口是什么? 现实生活中,有许多接口的例子,比如说电子设备上的充电接口,这个充电接口能干什么, ...

  4. JavaScript 基础学习(一)JavaScript 简介

    定义 JavaScript是基于对象和事件驱动的语言,应用与客户端.其中: 基于对象:提供好了很多对象,可以直接拿过来使用 事件驱动:html做网站静态效果,javascript动态效果(网页能根据客 ...

  5. IoU-aware Single-stage Object Detector for Accurate Localization

    网络的结构如下: 采用FPN结构,Backbone是RetinalNet,分成了P3~P7共5个Layer,分别训练不同尺寸的Box.每个Layer对应的Head有2个分支,包括一个单独的分支用来预测 ...

  6. 第十周CTF解答

    第十周write-up解题答案及过程 隐写诶 直接用WinRAR查看就能看到其flag{0ca175b9c0f726a831d895e269332461 } 第一题 将后缀名改为 rar ,发现压缩包 ...

  7. P1832题解 A+B Problem(再升级)

    万能的打表 既然说到素数,必须先打素数表筛出素数, 每个素数可以无限取,这就是完全背包了. 这次打个质数表: bool b[1001]={1,1,0,0,1,0,1,0,1,1,1,0,1,0,1,1 ...

  8. GCD相关

    板子: ? gcd(b, a % b) : a; } POJ1930 题意:给你一个无限循环小数,给到小数点后 9 位,要求这个数的分数形式. 解法: 要想解决这道题,首先应该了解如何将循环小数化为分 ...

  9. YARN安装和使用

    简介 Yet Another Resource Negotiator ,负责整个集群资源的调度,和管理,支持多框架资源统一调度(HIVE spark flink) 开启yarn 安装hadoop,可以 ...

  10. Html介绍,认识html标签

    什么是网页?网页就是我们我们提前写好的代码样式经过浏览器的渲染展示出来的样式效果.其实我们常说的上网就是浏览各式各样的网页,这些网页都是由html标签组成,下面就是一个简单的网页,效果图如下: 简单看 ...