1、多态发生的三个必备条件

  继承、重写、父类引用指向子类对象

2、注意

  当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

  方法的重写,也就是子类能够重写父类的方法

  当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。要想调用父类中被重写的方法,则必须使用关键字super。

3、好处

  可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

4、例子

 //父类
package com.test.five; public class Parent {
public void Test(){
System.out.println("我 是 父类");
}
} //子类一
package com.test.five; public class Child extends Parent {
public void Test(){
System.out.println("我 是大儿子");
}
public void Sex(){
System.out.println("我 是个男的");
}
}
//子类二
package com.test.five; public class Sister extends Parent{
public void Test(){
System.out.println("我也是个子类");
}
public void Sex(){
System.out.println("我是个女儿");
}
}
//测试类
package com.test.five; public class Test {
public static void main(String[] args) {
Parent p = new Child();
p.Test();//父类声明,子类创建,调用该对象的方法(子类父同时所拥有的方法)
Show(p);
Show(new Sister());
Show(new Child());
}
//测试类中的静态类方法,在测试类中可以直接调用此方法(不用再实例化类的对象)
public static void Show(Parent p){
p.Test();
if( p instanceof Child){
Child c = (Child)p;
c.Sex();
}else if(p instanceof Sister){
Sister s = (Sister)p;
s.Sex();
}
}
}

得出的结果是:

我 是大儿子
我 是大儿子
我 是个男的
我也是个子类
我是个女儿
我 是大儿子
我 是个男的

 5、注意(例子)

 //父类
package com.test.six; public class Emploee {
private String name;
private String address;
private int num;
public Emploee(String name,String address,int num){
System.out.println("Emploee的构造函数");
this.name = name;
this.address = address;
this.num = num;
}
public void check(){
System.out.println("Emploee中check的name:"+this.name+" ,address = "+this.address);
}
public String toString(){
return name+" "+address+" "+num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getNum() {
return num;
}
} //子类
package com.test.six; public class Salary extends Emploee {
private double salary;
//构造函数
public Salary(String name, String address, int num,double salary) {
super(name, address, num);
System.out.println("salary的构造函数");
setSalary(salary);
}
public double getSalary() {
return salary;
} public void setSalary(double salary) {
if(salary >=0.0){
this.salary = salary;
}
}
public void check(){
System.out.println("这是salary的check的方法");
System.out.println("Salary中的name="+getName()+" 薪资="+getSalary());
}
public double computePay() {
System.out.println("计算工资,付给:" + getName());
return salary/52;
}
}
//测试类
package com.test.six; public class Test {
public static void main(String[] args) {
Salary s = new Salary("张三", "北京", 3, 8000.0);
Emploee e = new Salary("李四", "上海", 5, 10000.0);
System.out.println("salary对象引用中的方法调用");
s.check();
s.computePay();
System.out.println("emploee对象引用中的方法调用");
e.check();
}
}

得到的结果如下:

 Emploee的构造函数
salary的构造函数
Emploee的构造函数
salary的构造函数
salary对象引用中的方法调用
这是salary的check的方法
Salary中的name=张三 薪资=8000.0
计算工资,付给:张三
emploee对象引用中的方法调用
这是salary的check的方法
Salary中的name=李四 薪资=10000.0

----一旦实例化一个对象,其执行顺序,首先:

在不涉及继承的前提下,当首次加载类时,按照如下顺序执行:
1、按照出现顺序先后执行静态成员变量定义与静态块;
2、按照出现顺序先后执行动态成员变量定义与动态块;
3、执行构造函数;
4、再次实例化对象时只执行第2、4步即可;

在涉及到继承时,按照如下顺序执行:
1、执行父类的静态成员变量定义与静态块,执行子类的静态成员变量与静态块
2、执行父类非静态成员变量定义与动态块,执行父类构造方法;
3、执行子类的非静态成员变量定义与动态块,执行子类构造方法;
注意:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在
调用父类构造函数中使用子类重写的方法。

例子一:

package com.test.seven;

public class TestOne {
private static TestOne t1 = new TestOne();
//静态变量
private static int i1;
private static int i2 = 2; public TestOne(){
i1++;
i2++;
}
public static void main(String[] args) {
TestOne t2 = new TestOne();
System.out.println("t2.i1 = " +t2.i1);
System.out.println("t2.i2 = "+t2.i2);
}
}

得到的结果如下:

t2.i1 = 2
t2.i2 = 3

执行过程:

  首先执行给t1、i1、i2分别给予初始值null,0,0,在执行TestOne t1 = new TestOne();
这样子i1++,i2++被执行,i1,i2都变成1,执行完毕后接着执行int i1 ,  i1,i2的值仍然是1,1,当执行int i2=2时,i2被赋予了值,即i1=1,i2=2;再执行
TestOne t2 = new TestOne(),i1,i2在执行++,此时i1=2,i2=3,输出i1,i2,结果就是:t2.i1=2,t2.i2=3通过上面代码可以知道:
系统默认的给予比通过等号的赋予先执行。

例子二:

package com.test.seven;

public class TestOne {
private static TestOne t1 = new TestOne();
//静态变量
private static int i1;
private static int i2 = 2;
//静态块
static{
System.out.println("静态块");
}
//动态块
{
System.out.println("动态块");
}
public TestOne(){
i1++;
System.out.println("i1--------------"+i1);
i2++;
System.out.println("i2--------------"+i2);
}
public static void main(String[] args) {
TestOne t2 = new TestOne();
System.out.println("t2.i1 = " +t2.i1);
System.out.println("t2.i2 = "+t2.i2); }
}

得到的结果如下:

 动态块
i1--------------1
i2--------------1
静态块
动态块
i1--------------2
i2--------------3
t2.i1 = 2
t2.i2 = 3

最新文章

  1. Linux 第04天
  2. Android Studio 修改字体
  3. 【BZOJ 1176】【Balkan 2007】Mokia
  4. 解决Ue4C++使用UMG之类的模块时出现的拼写错误
  5. ylbtech-LanguageSamples-XMLdoc
  6. ADB命令与monkey
  7. js 移动端上拉加载下一页通用方案
  8. 总结C语言字符检测函数:isalnum、isalpha...
  9. 通过编写一个简单的日志类库来加深了解C#的文件访问控制
  10. xpath语法笔记
  11. windows 下使用 sc 添加创建exe服务;
  12. LOJ#6433. 「PKUSC2018」最大前缀和 状压dp
  13. 【转】fiddler抓包HTTPS请求
  14. 微信js sdk的使用初步理解
  15. Python--CSV模块
  16. chrome ui源码剖析-Accelerator(快捷键)
  17. Integer源码分析
  18. 08_MySQL DQL_SQL99标准中的多表查询(内连接)
  19. winform 实现定位
  20. python 课堂笔记-购物车

热门文章

  1. 25. ClustrixDB 使用sierra_stats导出概率分布
  2. Angular 主从组件
  3. 揭秘Android Studio项目目录结构
  4. readyState xhr对象当前状态
  5. linux 加多播协议(IGMP)
  6. 解决phpmyadmin出现: Maximum execution time of 300
  7. leetcode-easy-listnode-234 Palindrome Linked List
  8. GetRGB下载
  9. 12个Sublime Text应用技巧[转载]
  10. Iris Classification on Keras