Java learning_Day4(下)

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

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

提取码:fobs

内容

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

Object 类

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

public class Person {
...
}

等价于

public class Person extends Object {
...
}

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)。

以下面程序为例

class Animal {
public String name;
Animal(String name) {
this.name = name;
}
} class Cat extends Animal {
public String eyesColor;
Cat(String name, String color) {
super(name);
eyesColor = color;
}
} class Dog extends Animal {
public String furColor;
Dog(String name, String color) {
super(name);
furColor = color;
}
} public class TestCasting { public static void main(String[] args) {
Animal a = new Animal("name");
Cat c = new Cat("cat name", "blue");
Dog d = new Dog("dog name", "black"); System.out.println(a instanceof Animal); //true
System.out.println(c instanceof Animal); //true
System.out.println(d instanceof Animal); //true
System.out.println(a instanceof Cat); //false Animal a1 = new Dog("dog name", "yellow"); //向上转型
System.out.println(a1.name ); //true
System.out.println(a1 instanceof Animal); //true
System.out.println(a1 instanceof Dog); //true Animal a2 = new Animal("name");
Dog d1 = (Dog)a2; //向下转型,!error
a2 = new Dog("dog name", "yellow");
System.out.println(d1.furColor);
}
}

输出结果

true
true
true
false
dog name
true
true
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。转型成功,编译器顺利执行。

而在程序段

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

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

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

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

动态绑定和多态(polymorphism)

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

以下面程序为例

class Animal {
private String name; Animal(String name) {
this.name = name;
} public void enjoy(){
System.out.println("叫声......");
}
} class Cat extends Animal {
private String eyesColor; Cat(String n,String c) {
super(n);
eyesColor = c;
} public void enjoy() {
System.out.println("猫叫声......");
}
} class Dog extends Animal {
private String furColor; Dog(String n,String c) {
super(n);
furColor = c;
} public void enjoy() {
System.out.println("狗叫声......");
}
} class Lady {
private String name;
private Animal pet; Lady(String name, Animal pet) {
this.name = name;
this.pet = pet;
} public void myPetEnjoy(){
pet.enjoy();
}
} public class TestPoly { public static void main(String args[]){
Cat c = new Cat("catname","blue");
Dog d = new Dog("dogname","black");
Lady l1 = new Lady("l1",c);
Lady l2 = new Lady("l2",d);
l1.myPetEnjoy();
l2.myPetEnjoy();
}
}

输出

猫叫声......
狗叫声......

在上述程序中,程序段

Lady(String name, Animal pet) {
this.name = name;
this.pet = pet;
}

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

抽象类

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

以下面程序为例

abstract class Animal {
private String name; Animal(String name) {
this.name = name;
} public abstract void enjoy();
} class Cat extends Animal {
private String eyesColor; Cat(String n,String c) {
super(n);
eyesColor = c;
} public void enjoy() {
System.out.println("猫叫声......");
}
} class Dog extends Animal {
private String furColor; Dog(String n,String c) {
super(n);
furColor = c;
} public void enjoy() {
System.out.println("狗叫声......");
}
} class Lady {
private String name;
private Animal pet;
Lady(String name,Animal pet) {
this.name = name;
this.pet = pet;
} public void myPetEnjoy() {
pet.enjoy();
}
} public class TestAbstract { public static void main(String args[]){
Cat c = new Cat("catname","blue");
Dog d = new Dog("dogname","black");
Lady l1 = new Lady("l1",c);
Lady l2 = new Lady("l2",d);
l1.myPetEnjoy();
l2.myPetEnjoy();
}
}

父类 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. Go语言基础之结构体(面向对象编程上)

    1 自定义类型和类型别名 1.1 自定义类型 Go语言中可以基于一些基本的数据类型,使用type关键字定义自定义类型的数据 . 自定义类型定义了一个全新的类型,该新类型具有基本数据类型的特性.自定义类 ...

  2. 珠峰-buffer-流事件

    #### Buffer // 字符串的二进制转10进制 let r = parseInt('11111111', 2); console.log(r); // 打印 255 // Number类型转为 ...

  3. mysql出现 Unknown column 'Password' in 'field list'

    linux安装了mysql之后初始化密码获取:出现了下面的内容,密码很尴尬,无法用root登录: grep 'temporary password' /var/log/mysqld.log [Note ...

  4. Linux系统开机显示BusyBox v1.22.1 built-in shell(ash) 解决方法

    BusyBox 是一个集成了三百多个最常用Linux命令和工具的软件.BusyBox 包含了一些简单的工具,例如ls.cat和echo等等,还包含了一些更大.更复杂的工具,例grep.find.mou ...

  5. python-20-迭代器是个什么东西?

    前言 迭代器.生成器.装饰器都有一个“器”,但他们之间没有什么关系. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 迭代器有两个基本的方法:iter()  ...

  6. C#面向对象--结构

    一.结构(Struct)是CTS中五种基本类型之一,是一种值类型,同样封装了同属一个逻辑单元的数据和行为,这些数据和行为通过结构中的成员表示:结构与类共享大多数相同的语法,但结构比类受到的限制更多,结 ...

  7. uniapp后台api设计(微信user表)

    MySQL 创建数据库: CREATE  DATABASE [IF NOT EXISTS] <数据库名> [[DEFAULT] CHARACTER SET <字符集名>] [[ ...

  8. SSH-Secure-Shell 3.2.9 build283版本,创建直接打开文件传输的快捷方式的方法

    2019-12-31 16:21:23 版本信息: 在安装目录下新建快捷方式 目标填写:"D:\SSH-Secure-Shell\SshClient.exe" /f 图标选择,系统 ...

  9. junit 运行(eclipse + IDEA)

    记得刚用IDEA  开发的时候, 什么都还不熟,以为junit 运行还跟eclipse 一样, 结果试了后才知道是不一样的. 现在刚好写junit 相关的,也就都记录下来吧 Eclipse:eclip ...

  10. 【终端命令】组管理 和 Ubuntu中的"sudo"命令

    一.超级用户root 1.超级用户和标准用户 Linux系统中的root账户通常 用于系统的维护和管理,对操作系统的 所有资源 具有所有访问权限. 在大多数版本的Linux系统中,都 不推荐 直接使用 ...