Java 面向对象概述原理: 多态、Object类,转型(8)
Java 面向对象概述原理: 多态、Object类,转型(8)
http://docs.oracle.com/javase/tutorial/java/IandI/override.html
Java 面向对象概述原理:
Java中多态性的体现、前提、好处、弊端、应用:
1,多态的体现:
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
2,多态的前提:
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。 3,多态的好处:
多态的出现大大的提高程序的扩展性。 4,多态的弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。 5,多态的应用
6,多态的出现代码中的特点(多态使用的注意事项)
/*
动物,
猫,狗。
*/ abstract class Animal
{
abstract void eat(); } class Cat extends Animal
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
} class Dog extends Animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void kanJia()
{
System.out.println("看家");
}
} class Pig extends Animal
{
public void eat()
{
System.out.println("饲料");
}
public void gongDi()
{
System.out.println("拱地");
}
} //----------------------------------------- class DuoTaiDemo
{
public static void main(String[] args)
{
//Cat c = new Cat();
//c.eat(); //Dog d = new Dog();
//d.eat();
//Cat c = new Cat();
/*
Cat c1 = new Cat();
function(c1); function(new Dog());
function(new Pig());
*/ //Animal c = new Cat();
//c.eat(); function(new Cat());
function(new Dog());
function(new Pig()); }
public static void function(Animal a)//Animal a = new Cat();
{
a.eat();
//a.catchMouse();
}
/*
public static void function(Cat c)//
{
c.eat();
}
public static void function(Dog d)
{
d.eat();
} public static void function(Pig p)
{
p.eat();
}
*/ }
多态的转型:
两种类型的类型转换
(1)向上类型转换(Upcast):将子类型转换为父类型。
对于向上的类型转换,不需要显示指定,即不需要加上前面的小括号和父类类型名。
(2)向下类型转换(Downcast):将父类型转换为子类型。
对于向下的类型转换,必须要显式指定,即必须要使用强制类型转换
多态示例代码 public class PolyTest
{
public static void main(String[] args)
{ //向上类型转换
Cat cat = new Cat();
Animal animal = cat;
animal.sing(); //向下类型转换
Animal a = new Cat();
Cat c = (Cat)a;
c.sing();
c.eat(); //编译错误
//用父类引用调用父类不存在的方法
//Animal a1 = new Cat();
//a1.eat(); //编译错误
//向下类型转换时只能转向指向的对象类型
//Animal a2 = new Cat();
//Cat c2 = (Dog)a2; }
}
class Animal
{
public void sing()
{
System.out.println("Animal is singing!");
}
}
class Dog extends Animal
{
public void sing()
{
System.out.println("Dog is singing!");
}
}
class Cat extends Animal
{
public void sing()
{
System.out.println("Cat is singing!");
}
public void eat()
{
System.out.println("Cat is eating!");
}
}
第二个问题:如何使用子类特有方法。
*/ /*
动物,
猫,狗。
*/ class Cat extends Animal
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
} class Dog extends Animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void kanJia()
{
System.out.println("看家");
}
} class Pig extends Animal
{
public void eat()
{
System.out.println("饲料");
}
public void gongDi()
{
System.out.println("拱地");
}
} //----------------------------------------- class DuoTaiDemo2
{
public static void main(String[] args)
{
//Animal a = new Cat();//类型提升。 向上转型。
//a.eat(); //如果想要调用猫的特有方法时,如何操作?
//强制将父类的引用。转成子类类型。向下转型。
///Cat c = (Cat)a;
//c.catchMouse();
//千万不要出现这样的操作,就是将父类对象转成子类类型。
//我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
//多态自始至终都是子类对象在做着变化。
// Animal a = new Animal();
// Cat c = (Cat)a; /*
毕姥爷 x = new 毕老师(); x.讲课(); 毕老师 y = (毕老师)x; y.看电影();
*/
function(new Dog());
function(new Cat()); }
public static void function(Animal a)//Animal a = new Cat();
{
a.eat();
/*
if(a instanceof Animal)
{
System.out.println("haha");
}
else
*/
if(a instanceof Cat)
{
Cat c = (Cat)a;
c.catchMouse();
}
else if(a instanceof Dog)
{
Dog c = (Dog)a;
c.kanJia();
} /*
instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)
*/ } }
/*
基础班学生:
学习,睡觉。
高级班学生:
学习,睡觉。 可以将这两类事物进行抽取。 */ abstract class Student
{
public abstract void study();
public void sleep()
{
System.out.println("躺着睡");
}
} class DoStudent
{ public void doSome(Student stu)
{
stu.study();
stu.sleep();
} } class BaseStudent extends Student
{
public void study()
{
System.out.println("base study");
}
public void sleep()
{
System.out.println("坐着睡");
}
} class AdvStudent extends Student
{
public void study()
{
System.out.println(" adv study");
}
} class DuoTaiDemo3
{
public static void main(String[] args)
{ DoStudent ds = new DoStudent();
ds.doSome(new BaseStudent());
ds.doSome(new AdvStudent()); // BaseStudent bs = new BaseStudent();
// bs.study();
// bs.sleep();
// AdvStudent as = new AdvStudent();
// as.study();
// as.sleep();
} }
/*
在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。 在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。 在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边。 */
class Fu
{
static int num = 5;
void method1()
{
System.out.println("fu method_1");
}
void method2()
{
System.out.println("fu method_2");
}
static void method4()
{
System.out.println("fu method_4");
}
} class Zi extends Fu
{
static int num = 8;
void method1()
{
System.out.println("zi method_1");
}
void method3()
{
System.out.println("zi method_3");
} static void method4()
{
System.out.println("zi method_4");
}
}
class DuoTaiDemo4
{
public static void main(String[] args)
{ // Fu f = new Zi();
//
// System.out.println(f.num);
//
// Zi z = new Zi();
// System.out.println(z.num); //f.method1();
//f.method2();
//f.method3(); Fu f = new Zi();
System.out.println(f.num);
f.method4(); Zi z = new Zi();
z.method4(); // Zi z = new Zi();
// z.method1();
// z.method2();
// z.method3();
}
}
/*
需求:
电脑运行实例,
电脑运行基于主板。
*/ interface PCI
{
public void open();
public void close();
} class MainBoard
{
public void run()
{
System.out.println("mainboard run ");
}
public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。
{
if(p!=null)
{
p.open();
p.close(); }
}
} class NetCard implements PCI
{
public void open()
{
System.out.println("netcard open");
}
public void close()
{
System.out.println("netcard close");
method();
} }
class SoundCard implements PCI
{
public void open()
{
System.out.println("SoundCard open");
}
public void close()
{
System.out.println("SoundCard close");
}
}
/*
class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void useNetCard(NetCard c)
{
c.open();
c.close();
}
} class NetCard
{
public void open()
{
System.out.println("netcard open");
}
public void close()
{
System.out.println("netcard close");
}
}
*/ class DuoTaiDemo5
{
public static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.run();
mb.usePCI(null);
mb.usePCI(new NetCard());
mb.usePCI(new SoundCard()); }
}
参考博客:
http://www.cnblogs.com/mengdd/archive/2012/12/25/2832288.html
http://www.cnblogs.com/jack204/archive/2012/10/29/2745150.html
多态的概念:
- 多态==晚绑定。
- 不要把函数重载理解为多态。因为多态是一种运行期的行为,不是编译期的行为。
- 多态:父类型的引用可以指向子类型的对象。比如 Parent p = new Child();
- 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的该同名方法。
- (注意此处,静态static方法属于特殊情况,静态方法只能继承,不能重写Override,如果子类中定义了同名同形式的静态方法,它对父类方法只起到隐藏的作用。调用的时候用谁的引用,则调用谁的版本。)
如果想要调用子类中有而父类中没有的方法,需要进行强制类型转换,如上面的例子中,将p转换为子类Child类型的引用。
因为当用父类的引用指向子类的对象,用父类引用调用方法时,找不到父类中不存在的方法。这时候需要进行向下的类型转换,将父类引用转换为子类引用。
/*
多态:可以理解为事物存在的多种体现形态。 人:男人,女人 动物:猫,狗。 猫 x = new 猫(); 动物 x = new 猫(); 1,多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
2,多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。 3,多态的好处
多态的出现大大的提高程序的扩展性。 4,多态的弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。 5,多态的应用 */ /*
动物,
猫,狗。
*/ abstract class Animal
{
abstract void eat(); } class Cat extends Animal
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
} class Dog extends Animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void kanJia()
{
System.out.println("看家");
}
} class Pig extends Animal
{
public void eat()
{
System.out.println("饲料");
}
public void gongDi()
{
System.out.println("拱地");
}
} //----------------------------------------- class DuoTaiDemo
{
public static void main(String[] args)
{
//Cat c = new Cat();
//c.eat(); //Dog d = new Dog();
//d.eat();
//Cat c = new Cat();
/*
Cat c1 = new Cat();
function(c1); function(new Dog());
function(new Pig());
*/ //Animal c = new Cat();
//c.eat(); function(new Cat());
function(new Dog());
function(new Pig()); }
public static void function(Animal a)//Animal a = new Cat();
{
a.eat();
//a.catchMouse();
}
/*
public static void function(Cat c)//
{
c.eat();
}
public static void function(Dog d)
{
d.eat();
} public static void function(Pig p)
{
p.eat();
}
*/ }
什么是多态:
- 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。
- 多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
- 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
- 多态的作用:消除类型之间的耦合关系。
- 现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
多态存在的三个必要条件,要求大家做梦时都能背出来!
- 多态存在的三个必要条件
- 一、要有继承;
- 二、要有重写;
- 三、父类引用指向子类对象。
多态的好处:
1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。
Java中的多态:
abstract class 动物
{
abstract void eat();
} class Dog extends 动物
{
public void eat()
{
//骨头;
}
} class 猫 extends 动物
{
public void eat()
{
//吃鱼;
}
} class 猪 extends 动物
{
public void eat()
{
//饲料;
}
} class Demo
{
public void method(动物 x)//new Dog(); new 猫();
{
x.eat();
}
/*
public void method(猫 x)
{
x.eat();
}
public void method(Dog x)
{
x.eat();
}
public void method(猪 x)
{
x.eat();
}
*/
} class Main
{
public static void main(String[] args)
{
Demo d = new Demo();
d.method(new Dog());
d.method(new 猫());
}
} 动物 x = new 猫();
//猫 x = new 猫(); 一。表现:
父类或者接口的引用指向了或者接收了自己的子类对象。 二。前提:
1,类与类之间要有关系。继承,实现。
2,通常都会有覆盖。 三。好处:
预先定义的程序可以运行后期程序的内容。
增强了程序的扩展性。 四。弊端:
虽然可以预先使用,但是只能访问父类中已有的功能,运行的是后期子类的功能内容。
不能预先使用子类中定义的特有功能。 五。多态的注意事项:
在代码中。
对于成员函数:Fu f = new Zi(); f.method();
编译时期:看左边。
运行时期:看右边。
因为成员函数有一个覆盖操作。
毕姥爷和毕老师的故事。 对于非私有的实例变量,
静态变量,静态方法。 编译和运行都看左边。 老师要求记住结论。有空闲时间,就想想为什么? 六。转型。
子类对象被父类引用:子类对象在向上转型。
将指向子类对象的父类应用转换成子类类型引用:向下转型。 毕姥爷和毕老师的故事。
class 毕姥爷
{} class 毕老师 extends 毕姥爷
{} 毕姥爷 ly = new 毕老师();//毕老师向上转型为了毕姥爷。向上转型 毕老师 ls = (毕老师)ly; //将代表毕老师对象的父类引用ly强制转换成了毕老师类型。向下转型。 七。应用
电脑使用。主板运行。 class MainBoard
{
public void run()
{
//主板运行;
}
public void usePCI(PCI p)//PCI p = new NetCard();
{
if(p!=null)
{
p.open();
p.close();
}
}
} //为了提高主板功能的扩展性。
//定义了规则。让后期的出现的功能板块,只要覆盖该规则,就可以被这个主板使用。
interface PCI
{
void open();
void close();
} class MainDemo
{
public static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.run();
mb.usePCI(null);
mb.usePCI(new NetCard()); }
} class NetCard implements PCI
{
public void open(){}
public void close(){}
} Object:是java中所有对象的直接或者间接的父类。
它里面的方法都所有对象都具备的。
常见方法:
boolean equals(Object obj):用于比较两个对象是否相同。
String toString(): 获取对象的字符串表现形式 类名@哈希值
getClass().getName()+"@"+Integer.toHexString(hashCode());
Class getClass():获取正在运行的对象所属的字节码文件的对象。也就是说如果Demo d = new Demo();
d.getClass():获取的就是d执行的对象所属的字节码文件Demo.class对象。 通常在自定义对象时,因为对象中都有自己特有的描述,
所以都会建立对象自身的特有比较方法,或者字符串表现形式。
也就是说,会覆盖Object中的方法。 /*
Demo d1 = new Demo();
Demo d2 = new Demo();
d1.getClass() == d2.getClass();
*/ class Demo //extends Object
{
public String toString()
{
this.getClass().getName()+"#"+Integer.toHexString(this.hashCode());
}
} class Fu
{
void show(){System.out.println("fu show");}
}
class Zi extends Fu
{
void function()
{
super.show();
//this.show();
}
void show(){System.out.println("zi show");}
} /* class Computer
{
private MainBoard mb; Computer()
{
mb = new MainBoard();
}
public void play()
{
mb.run();
}
}
*/
Java 面向对象概述原理: 多态、Object类,转型(8)的更多相关文章
- JS面向对象(3) -- Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...
- Java学习笔记18(Object类)
Object类是Java中最顶层的父类,所有类都是它的子类,接口不继承它 Object类中的方法: 官方资料:boolean equals(Object obj) 指示其他某个对象是否与此对象&qu ...
- JAVA 面向对象中的多态
多态是继封装.继承之后,面向对象的第三大特性. 现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态. Java作为面向对象的语言,同样可以描述一个 ...
- Java(215-231)【Object类、常用API】
1.Object类的toString方法 java.lang.Object 类 Object 是类层次结构的根(父)类. 每个类(Person,Student...)都使用 Object 作为超(父) ...
- Java面向对象概述
一.什么是面向对象? 现实世界中,随处可见的一种事物就是对象,对象是事物存在的实体,如人类.书桌.计算机.高楼大厦等.人类解决问题的方式总是将复杂的事物简单化,于是就会思考这些对象都是由哪些部分组成的 ...
- Java面向对象概述和三大特性
Java 是面向对象的高级编程语言,类和对象是 Java 程序的构成核心.围绕着 Java 类和 Java 对象,有三大基本特性:封装是 Java 类的编写规范.继承是类与类之间联系的一种形式.而多态 ...
- java源码解析之Object类
一.Object类概述 Object类是java中类层次的根,是所有类的基类.在编译时会自动导入.Object中的方法如下: 二.方法详解 Object的方法可以分成两类,一类是被关键字fin ...
- Java学习(API及Object类、String类、StringBuffer字符串缓冲区)
一.JAVA的API及Object类 1.API 概念: Java 的API(API: Application(应用) Programming(程序) Interface(接口)) Java API就 ...
- Java:不得不知的Object类
目录 一.equals 1.equals与==有啥区别? 2.equals方法的规范 3.instanceof 和getClass() 4.其他总结 二.hashCode 1.hashCode的规范 ...
随机推荐
- Oracle的操作经验
采用Oracle进行sql语句 建表并设置主键,主键自增,某一字段唯一性约束等 <---如果表存在则删除---> declare num number; begin select coun ...
- systemctl无法停掉keepalived
这个问题搞了好半天,记录一下,启停都是用的systemctl 起初是测试vip漂移时候发现,主备节点都开启keepalived的状况下,一切正常,主节点的vip也可以访问. 第一次停掉主节点的keep ...
- reduce()、filter()、map()、some()、every()、...展开属性
reduce().filter().map().some().every()....展开属性 这些概念属于es5.es6中的语法,跟react+redux并没有什么联系,我们直接在https:// ...
- java高并发核心类 AQS(Abstract Queued Synchronizer)抽象队列同步器
什么是AQS? 全称: Abstract Queued Synchronizer: 抽象队列同步器 是 java.util.concurrent.locks包下的一个抽象类 其编写者: Doug Le ...
- HZNU-ACM寒假集训Day12小结 数论入门
符号说明 a|b a整除b (a,b) a与b的最大公因数 [a,b] a与b的最小公倍数 pα||a pα|a但pα+1∤a a≡b(mod m) a与b对模m同余 a ...
- 压测工具siege和wrk
siege压测工具 安装: wget http://download.joedog.org/siege/siege-3.0.8.tar.gz cd siege-3.0.8 ./configure ma ...
- spring boot配置druid连接池连接mysql
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- lastz
lastz sequence1.fasta sequence2.fasta 其中,sequence1.fasta是reference genome :sequence2.fasta是需要比对的geno ...
- 每天一点点之 taro 框架开发 - taro路由及传参
1.路由 taro的路由是自带的,不需要我们额外配置,只需要我们在app.js下config中配置pages即可 class App extends Component { config = { pa ...
- 【pwnable.kr】 mistake
又一道pwnable,我还没放弃.. ssh mistake@pwnable.kr -p2222 (pw:guest) 源代码如下: #include <stdio.h> #include ...