子类父类拥有同名的方法时……

(这个程序是不能运行的)

packageyanzheng;

public classParentChildTest {

public static voidmain(String[]args) {

Parentparent=newParent();

parent.printValue();

Childchild=newChild();

child.printValue();

parent=child;

parent.printValue();

parent.myValue++;

parent.printValue();

((Child)parent).myValue++;

parent.printValue();

}

}

class Parent{

public int myValue=100;

public voidprintValue() {

System.out.println("Parent.printValue(),myValue="+myValue);

}

}

class Child extendsParent{

public int myValue=200;

public voidprintValue() {

System.out.println("Child.printValue(),myValue="+myValue);

}

}

总结:子类父类拥有同名的方法时:

*当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。

*这个特性实际上就是面向对象“多态”特性的具体表现。

*如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。

*如果子类被当作父类使用,则通过子类访问的字段是父类的!

牢记:

在实际开发中,要避免在子类中定义与父类同名的字段。不要自找麻烦!

附录:网络上摘取的一些代码和解释,可以帮助理解。

例1:

public class A {protected String a = "1";public String getA(){return this.a;}}public class B extends A {protected String a = "2";//    public String getA(){//        return a;//    }public static void main(String[] args) {B x = new B();System.out.println(x.getA());}}

输出的是1,父类的方法看到的变量是父类中的a。如果B中也写一个getA方法,看到的a就是子类中的a了。其实就是可见性的问题。父类和子类的变量是同时存在的,即使是同名。子类中看到的是子类的变量,父类中看到的是父类中的变量。它们互相隐藏,而同名的方法则是实实在在的覆盖。如A x = new B();x是一个B,也是一个A,那么调用方法时,是根据对象的实际类型调用的,实际类型是B,所以永远调用子类的方法。而访问成员变量就不同了,它是B时,访问的是子类的成员变量,转型为A的话,访问的就是父类的成员变量了。

例2:

//Main.javaclass c{public int name = 12;}class d extends c{d(){name =13;}void d2(){System.out.println(super.name);}}public class Main{public static void main(String[]args){d d1 = new d();System.out.println(d1.name);d1.d2();}}//运行结果为:13,13//Main1.javaclass c{public int name = 12;}class d extends c{int name =13;void d2(){System.out.println(super.name);}}public class Main{public static void main(String[]args){d d1 = new d();System.out.println(d1.name);d1.d2();}}//运行结果为:13,12

首先要了解super这个关键字的意思,是调用父类的意思,void d2(){System.out.println(super.name);}这句话就是调用父类的name,虽然子类里面有一个name,但是并不是覆盖了父类里面的name,而只是父类的name隐藏起来了,使得直接调用子类里面的name显示的是子类定义的name。第一个main。Java,不用说,子类没有定义name变量,并且父类里面的name变量不是private,子类可以直接继承name,这样子类和父类就共用一个name变量

如果父类定义了一个方法。子类重写了这个方法。那么这两个方法其实也是拥有各自的内存。

例3:

class Parent{

int i=10;// 父类变量

public void setI(int i){

this.i=i;

}

}

class Son extends Parent{

int i=10;// 子类与父类同名的变量

public static void main(String args[]){

Son son=new Son();

System.out.println("son.i="+son.i);

son.setI(100);

System.out.println("After setI(100) : son.i="+son.i);

Parent parent=son;

System.out.println("See son as Parent : son.i="+parent.i);

}

}

在这段代码中,子类定义了一个父类中同名的成员变量int i,在父类中有一个对 i 赋值的方法setI(),而在子类中没有定义这个方法。当子类调用继承而来的setI()方法对成员变量i进行改变,直接打印son.i时,成员变量i然而却没有改变。当但当把son当作Parent类型来使用,再打印它的成员变量i时,输出的结果就对了,是setI()改变之后的值。

java中类是分层次的,当子类和父类的定义同名时,父类变量被隐藏,父类的实例方法被重写,静态方法属于类级别的方法,在子类和父类中互不相碍。

例4:

在java 中,当我们子类要重写父类中的方法,如果父类的方法有异常声明,那么子类重写这个方法时候,所要声明的异常不应该比父类的大。只能是小等,或者可以没有。原因如下。

假如我们自定意义一个异常:

public class MyException extends Exception {

public MyException(String message) {}public MyException() {}

}

那么我们有一个父类它将有一个方法,将声明抛出这个异常。我们把它做成抽象的(无所谓)

public abstract class ParentException {

public abstract void test() throws MyException;

}

那么将有一个类使用到上面这个类

public class ExceptionTest {

private ParentException exception;public ExceptionTest(ParentException exception){

this.exception=exception;

}public void app(){

try {

exception.test();

} catch (MyException e) {

e.printStackTrace();

}

}

}

对于以上的try~catch 我们就直接捕获MyException异常。这是正确的,它在编译的时候是没有问题的。

假如,有一个ParentException的有一个子类

public class ChildException extends ParentException{

public void test() throws Exception{ }

}

他的方法可以声明抛出比父类大的异常,假如它是正确的。那么问题来了。当我们执行ExceptionTest类的时候,我们以这个子类做为对象传进去。exception.test();这个地方将在运行的时候实际调用的是ChildException这个子类的test()方法,而它的声明抛 出却是比父类大的异常,这就使得在ExceptionTest类中,捕获异常处出现了毛病,因为它无法捕获Exception异常。综上所诉,子类重写父类的方法时候不能声明抛出比父类大的异常。

例5:关于方法的重写Overriding和重载Overloading。

方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。Overloaded的方法是可以改变返回值的类型。也就是说,重载的返回值类型可以相同也可以不同。

1、重载(Overloading)

a、方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载Overloading是一个类中多态性的一种表现。b、Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法,这就是多态性。

c、重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。

2、重写(Overriding)

a、父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。在Java中子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。b、若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。

c、子类函数的访问修饰权限不能少于父类的

java 子类的同名方法_子类父类拥有同名的方法时……相关推荐

  1. java重写父类方法_重写父类方法

    在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写.需要注意的是,在子类中重写的方法需要和父类被重写的方法具有相同的方法名.参数列表以及返 ...

  2. controller调用controller的方法_你想过 Controller 这些方法里的参数是如何工作的吗?...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 前言 SpringMVC是目前主流的Web MVC框架之一.Spr ...

  3. python的del方法_关于python:__ del__方法是什么,如何调用它?

    我正在阅读代码. 在其中定义了__del__方法的类. 我发现此方法用于销毁类的实例. 但是,我找不到使用此方法的地方. 其主要原因是我不知道如何使用此方法,可能不是这样:obj1.del(). 因此 ...

  4. C# 子类实例化基类 基类使用不了子类的方法_老话题:6个方法,检验你有没有正确使用设计模式...

    方法一:设计模式是为了消除继承 大部分设计模式,是让你在在面向对象的基础上尽量消除继承的手段.所以,如果你用了一些设计模式,减少了继承,那你八成用对了.如果你用了一大堆设计模式,然而继承却越来越频繁, ...

  5. java构造反射和函数_反射类的构造函数和方法

    开始学习Javaweb,看到了反射,现在还没有用上,先把基础的写上来吧 package com.april.write; public class Grade { private int num; p ...

  6. java接口参数默认值_下面关于setMaxAge(int expires)方法参数默认值的描述中,正确的是(5.0分)_学小易找答案...

    [单选题]下面选项中,用于在web.xml中配置监听器的元素是(5.0分) [填空题]Cookie技术用于将会话过程中的数据保存到( )中,从而使浏览器和服务器可以更好地进行数据交互.(5.0分) [ ...

  7. java jdom 读取xml文件_使用Jdom读取XML文件方法

    使用Jdom读取XML文件方法,学习Spring时,我们经常看到很多xml配置文件,Spring通过在配置文件中的配置,使用IOC(控制反转),从而实现代码的灵活性,本篇我就为大家介绍一种解析xml方 ...

  8. java list sublist方法_聊聊ArrayList中的subList方法

    开发过程中遇到的坑 开发过程经常会使用subList做分页处理. 比如下面的代码 while(pageIndex < maxSize) { List temp = userIds.subList ...

  9. java环境变量配置检验_配置检测JDK环境的方法整理,非常详细

    如果你的电脑中没有安装JDK软件,就无法顺利进行Java程序开发,当然了,JDK安装完成,还需要配置环境变量.如果你不知道如何操作,本文介绍了在Win10系统中配置并检测JDK环境变量的方法流程,大家 ...

最新文章

  1. MTD的坏块管理(一)-快速了解MTD的坏块管理
  2. RUST直接升钢指令_[译]参照TypeScript学习Rust-part-1
  3. iOS架构-静态库.a的打包及使用(2)
  4. matlab2011实验3,matlab实验3探索.doc
  5. PHP7 学习笔记(六)403 Forbidden - WAMP Server 2.5
  6. java InputStream的使用
  7. java random算法_负载均衡--随机算法(Random)
  8. CVPR2020十个顶级开源数据集
  9. 一个完全摆脱findViewById的自动绑定库
  10. 【干货】JS 限制input文本框输入
  11. 《Cocos2D-x权威指南》——3.1 节点类
  12. 常用网站网址、名称、logo列表
  13. 转行开始的前端填坑之路
  14. 解决DELL WIN7 bootmgr is missing
  15. Word文件怎么在方框里面打对勾
  16. 【iCheck基本用法的使用】
  17. VMware Workstation 15 Pro 秘钥
  18. 华为OD机试真题 C++ 实现【预订酒店】【2022.11 Q4 新题】
  19. 不能管家的AI机器狗不是好宠物?
  20. Uwsgi 编码问题 UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in positio

热门文章

  1. 剑灵元气无敌服务器维修到什么时候,《剑灵》周年庆有哪些活动 周年庆活动任务兑换攻略...
  2. DIV或Divide命令 等分对象
  3. Spark系列之Spark启动与基础使用
  4. PFC6.0documentation_Program Guide
  5. 孟森先生收徒仪式在翔龙商务酒店举行
  6. pytorch BatchNorm1d 输入二维和三维数据的区别
  7. 枚举注解反射整合详解
  8. 神武3手游请授权位置服务器,神武3手游双平台-盛名天下开服时间表_神武3手游新区开服预告_第一手游网手游开服表...
  9. vue中使用echarts绘柱形图+折线图
  10. 用Qt模仿酷我音乐盒写的个性菜单