精华内容
下载资源
问答
  • 上学期学了java,一个暑假没有用,很多java的“精髓”都忘记了。周末在写数据结构的作业的时候,...调用重写方法首先,我创建了一个MyAbstractList的父类,里面是一些实现线性表的方法。然后创建了一个CircularLin...

    上学期学了java,一个暑假没有用,很多java的“精髓”都忘记了。周末在写数据结构的作业的时候,要求写一个循环链表的类,并且继承之前写的一个线性表的类。因为重写的一些重要的东西忘记了,花了大量的时间一直在报空指针异常,终于发现了问题,并请教了前辈才算是解决了这个问题。

    调用重写方法

    首先,我创建了一个MyAbstractList的父类,里面是一些实现线性表的方法。然后创建了一个CircularLinkedList的子类,继承了MyAbstractList类中的方法。其中,父类里面有两个add()方法,如下:

    public void add(E e) {

    this.add(index,E e);

    System.out.println("Add parent o");

    }

    public void add(int index,E e) {

    System.out.println("Add parent t");

    }

    接着,我在子类,也就是CircularLinkedList类里面重写了这两个方法,如下:

    @Override

    public void add(E element) {

    super.add(E e);

    System.out.println("Add child o");

    }

    @Override

    public void add(int index,E element) {

    super.add(index,E e);

    System.out.println("Add child t");

    }

    在测试类里面创建了一个子类对象,并且调用了add(E element)方法,代码如下:

    CircularLinkedListlist1 =new CircularLinkedList();

    list1.add(3);

    }

    我的脑海里这段程序的输出应该是这样的:(很久以前写的,现在也忘了当时怎么想的,总之不对)

    Add child o

    Add parent o

    Add parent t

    然而事实并非如此,真正的输出是这样的:

    Add parent t

    Add child t

    Add parent o

    Add child o

    这是为什么呢?原来,因为我new的对象是子类,也就是CircularLinkedList类,所以在父类中的 this.add(int index,E e)时,调用的并非是父类中的add(int index,E e),而是子类中的add(int index,E e)。这样一来,问题就逐渐明了了。

    Java中的多态

    要满足多态的条件,子类要重写父类的方法。多态是父类引用指向子类对象。

    值得注意的是,多态中,若子类中没有重写方法,则就算子类中的方法名和父类中的方法名一样(即子类仅仅重载了父类中的方法),那么不能构成多态,而子类中的这个方法就和它自己创建的一个普通方法是一样的,和父类并没有关系。

    另外,在使用多态时,调用子类方法的时候会先去看引用类型中是否有同样的方法,即会先去看此方法是否被重写,如果此方法不是被重写的,也就是说,调用的子类中的方法是重载父类中的方法,父类中实际上是没有这个方法的,那么在调用这个方法的时候就会报错。例子如下:

    package test;

    public class TestPolymorphic {

    public static void main(String[] args) {

    A test=new B();

    test.printl();

    }

    }

    class A{

    void printl(int x) {

    System.out.println("x is "+x);

    }

    }

    class B extends A{

    void printl() {

    System.out.println("y is null");

    }

    }

    编译器会给出如下错误提示:

    Exception in thread "main" java.lang.Error: Unresolved compilation problem:

    The method printl(int) in the type A is not applicable for the arguments ()

    当代码修改之后,如下:

    public static void main(String[] args) {

    A test=new B();

    test.printl(10);

    }

    方法会调用A类中的printl()方法,并且输出结果:x is 10

    而当子类中重写了父类中的方法之后,即代码如下:

    package test;

    public class TestPolymorphic {

    public static void main(String[] args) {

    A test=new B();

    test.printl(10);

    }

    }

    class A{

    void printl(int x) {

    System.out.println("x is "+x);

    }

    }

    class B extends A{

    void printl(int y) {

    System.out.println("y is null");

    }

    }

    调用的则是子类中的printl()方法,输出结果为:y is null

    展开全文
  • 我希望在解析编译的类文件时,在方法体内调用anther类来替换对给定类的调用…换句话说,是否有一种方法可以检测方法中给定类的用法,并使用类似javaassist的方法替换方法的那一部分.例如..如果我有编译版本的class A { ...

    我希望在解析编译的类文件时,在方法体内调用anther类来替换对给定类的调用…

    换句话说,是否有一种方法可以检测方法中给定类的用法,并使用类似javaassist的方法替换方法的那一部分.

    例如..如果我有编译版本的

    class A { public int m() { int i = 2; B.multiply(i,i); return i; } }

    有没有一种方法可以检测B的使用,然后改变要执行的代码

    class A { public int m() { int i = 2; C.divide(i,i); return i; } }

    我知道另一种方法是编写一个解析器来grep源文件以供使用,但我更喜欢更优雅的解决方案,例如使用反射来生成新的编译类文件.

    有什么想法吗 ?

    解决方法:

    正如@djna所说,可以在加载字节码文件之前对其进行修改,但您可能不希望这样做:

    >执行代码修改的代码可能很复杂且难以维护.

    >已修改的代码很可能难以调试.首先,源级调试器将显示不再与您实际编辑的代码对应的源代码.

    字节码重写在某些情况下很有用.例如,JDO实现使用字节码重写来将对象成员提取替换为对持久性库的调用.但是,如果您可以访问这些文件的源代码,则可以通过预处理(或生成)源代码获得更好(即更易维护)的解决方案.

    编辑:AOP或Groovy听起来也像是可行的替代方案,具体取决于您预期的重写程度.

    标签:java,methods,reflection,bytecode-manipulation

    来源: https://codeday.me/bug/20190527/1160363.html

    展开全文
  • 本打算继承一个API中Parent类(Parent继承自GrandParent类),重写其中service方法,copy了Parentservice方法。不过发现Parentservice中也有super.service方法。当时考虑直接调用GrandParentservice方法。...
    本打算继承一个API中的Parent类(Parent继承自GrandParent类),重写其中的service方法,copy了Parent的service方法。不过发现Parent的service中也有super.service方法。当时考虑直接调用GrandParent的service方法。。。未遂(包括反射也不行)。正好看到老外写的一篇文章,翻译:
    在Son类里面写一个test方法:
    展开全文
  • 如果父类构造器调用了被子类重写的方法,且通过子类构造函数创建子类对象,调用了这个父类构造器(无论显示还是隐式),就会导致父类在构造时实际上调用的是子类覆盖的方法(你需要了解java继承中的初始化机制)。...

    [转]【原文】

    1.如果父类构造器调用了被子类重写的方法,且通过子类构造函数创建子类对象,调用了这个父类构造器(无论显示还是隐式),就会导致父类在构造时实际上调用的是子类覆盖的方法(你需要了解java继承中的初始化机制)。

    例子:

    public abstract classFather {

    publicFather() {

    display();

    }

    public voiddisplay() {

    System.out.println("Father's display");

    }

    }

    public classSonextendsFather {

    publicSon() {

    }

    public voiddisplay() {

    System.out.println("Son's display");

    }

    public static voidmain(String[] args) {

    newSon();

    }

    }

    7111019.html

    输出为:

    Son's display

    7111019.html

    这种机制有优点,不过有时也存在问题。

    优点:通过继承相同的父类,初始化子类时,父类会调用不同子类的不同复写方法,从而实现多态性。

    举一个Spring中的例子:

    Spring中可以通过为每个DAO注入一个已经用DataSource初始化的JdbcTemplate,来执行SQL语句。但是每个DAO都通过编码实现这个注入就产生了大量代码冗余,于是Spring提供了一个JdbcDaoSupport类,DAO只需继承这个类,就会自动注入已初始化好的JdbcTemplate,那么是如何做到的呢?查看源码:

    JdbcDaoSupport继承了DaoSupport:

    7111019.html

    public abstract classJdbcDaoSupportextendsDaoSupport

    DaoSupport实现了InitializingBean接口,该接口只有一个void afterPropertiesSet() throws Exception;

    方法,Spring会在初始化Bean的属相后查看这个Bean是否实现了InitializingBean接口,如果继承了就会自动调用afterPropertiesSet方法。

    7111019.html

    那么看一下DaoSupport中的afterPropertiesSet是如何实现的:

    public final voidafterPropertiesSet()throwsIllegalArgumentException, BeanInitializationException {

    // Let abstract subclasses check their configuration.

    checkDaoConfig();

    // Let concrete implementations initialize themselves.

    try{

    initDao();

    }

    catch(Exception ex) {

    throw newBeanInitializationException("Initialization of DAO failed", ex);

    }

    }

    他这里调用了checkDaoConfig方法,此方法是抽象方法,真正运行时会去调用子类重写过的该方法。

    查看JdbcDaoSupport如何重写checkDaoConfig():

    @Override

    protected voidcheckDaoConfig() {

    if(this.jdbcTemplate ==null) {

    throw newIllegalArgumentException("'dataSource' or 'jdbcTemplate' is required");

    }

    }

    7111019.htmlJdbcDaoSupport会检查jdbcTemplate是否注入,没注入会抛出异常!这就完成了注入检测,通过子类实现具体检测的过程!这也就是当你的DAO继承了JdbcDaoSupport,但是在XML配置DAO时没有配置DataSource属性会抛出异常的原因。

    那么JdbcTemplate是何时注入的呢?观察JdbcDaoSupport源码,发现setDataSource()方法,框架根据XML配置初始化DAO时,会调用属性的set方法注入,如果DAO没有该set方法,则调用父类的。也就是调用JdbcDaoSupport的setDataSource方法,此时便创建了DAO执行SQL语句需要的jdbcTemplate。

    /**

    * Set the JDBC DataSource to be used by this DAO.

    */

    public final voidsetDataSource(DataSource dataSource) {

    if(this.jdbcTemplate ==null|| dataSource !=this.jdbcTemplate.getDataSource()) {

    this.jdbcTemplate = createJdbcTemplate(dataSource);

    initTemplateConfig();

    }

    }

    缺点:如果在父类构造函数中调用被子类重写的方法,会导致子类重写的方法在子类构造器的所有代码之前执行,从而导致子类重写的方法访问不到子类实例变量的值,因为此时这些变量还没有被初始化。

    展开全文
  • Java调用被子类重写的方法

    千次阅读 2018-10-13 20:34:24
    Java调用被子类重写的方法 在访问权限允许的情况下,子类可以调用父类的方法,这是因为子类继承父类就会获得父类的定义的成员不变量和方法;但父类却不能调用子类的方法,因为父类无法知道会被什么子类所继承,它...
  • Java调用子类重写方法

    千次阅读 2015-06-05 18:27:21
    以下情况下父类可以调到子类的重写方法 package com.skymr.learn; /** * 调用子类重写方法 * @author skymr * */ public class SubParentTest2 extends ParentClass2{ private String name; public ...
  • 1.若是父类构造器调用了被子类重写的方法,且经过子类构造函数建立子类对象,调用了这个父类构造器(不管显示仍是隐式),就会致使父类在构造时实际上调用的是子类覆盖的方法(你须要了解java继承中的初始化机制)。java...
  • 在本篇文章里小编给大家整理了关于java子类调用父类的方法中包含子类重写的实例方法以及相关知识点,需要的朋友们可以学习下。
  • @Override //父类中hascode()算出hashcode值 s[0]*31^(n-1) + s[1]*31^(n-2) + ...... public int hashCode() {// 重写hashCode方法 final int PRIME = 31; int result = 1; result = PRIME * result + ((bz
  • 应该是“以上代码段//处应该怎样才能调用已经被子类重写的方法,显示出"source method"”,目的是调用父类被重写的方法,而不是显示“source method”,如果只是显示,我创建一个父类就好了 回答1楼:明显不行啊,这...
  • # 看题目是不是很绕,这个我也不知道怎么才能更简单表达了# 先看代码:public class Common {public static void main(String[] args) {Sub sub = new Sub();sub.testSub();}}class Parent {protected boolean ...
  • 这时候在子类重写的方法中使用super来调用父类被重写的方法,究竟调用的是父类未被重写的方法,还是已被重写的方法呢。 public class Me { public void m(){ System.out.println("Me"); } } publ...
  • 父类调用被子类重写的方法
  • # 看题目是不是很绕,这个我也不知道怎么才能更简单表达了# 先看代码:public class Common {public static void main(String[] args) {Sub sub = new Sub();sub.testSub();}}class Parent {protected boolean ...
  • 当我们重写了父类方法后,又想同时调用父类的方法,而不是已经重写的方法,可以这样: public class main{ static Scanner cin = new Scanner(System.in); public static void main(String[] args) { Sun ...
  • 面试中经常考到方法的调用,以及构造函数先后顺序。 例子 定义父类,申明方法say() public class TestParent { protected static String name = "parent"; TestParent(){ say(); } public void say(){ ...
  • 1.如果父类构造器调用了被子类重写的方法,且通过子类构造函数创建子类对象,调用了这个父类构造器(无论显示还是隐式),就会导致父类在构造时实际上调用的是子类覆盖的方法(你需要了解java继承中的初始化机制)。...
  • 1.如果父类构造器调用了被子类重写的方法,且通过子类构造函数创建子类对象,调用了这个父类构造器(无论显示还是隐式),就会导致父类在构造时实际上调用的是子类覆盖的方法(你需要了解java继承中的初始化机制)。...
  • java中子类重写父类方法调用父类同名方法: 在学装饰者模式时候发现子类重写父类方法调用父类同名方法: public abstract class Beverage { String description = "Unknown Beverage"; public String ...
  • Java的方法重写调用

    千次阅读 2018-10-16 21:11:20
    上学期学了java,一个暑假没有用,很多java的“精髓”都忘记了。周末在写数据结构的作业的时候,要求...调用重写方法 首先,我创建了一个MyAbstractList的父类,里面是一些实现线性表的方法。然后创建了一个Circula...
  • 方法重写的校验注解: @overrideJava建议在重写的方法上面加上一个@override注解。 方法一旦加了这个注解,那就必须是成功重写父类的方法,否则报错。@override优势:可读性好,安全,优雅。方法重写的要求:子类重写...
  • 以前对java中多态的理解只停留在重写Overriding和重载Overloading上,但是对于经过重写,重载的方法的调用顺序,尤其涉及父类对象以子类实例化,又或者经过向上向下转型后,经过重写的方法调用的优先级往往会使人...
  • 当子类和父类存在同一个方法,子类重写了父类的方法,程序在运行时调用方法是调用父类的方法还是子类的重写方法呢,这应该是我们在初学Java时遇到的问题。这里首先我们将确定这种调用何种方法实现或者变量的操作叫做...
  • java子类调用父类的方法中包含子类重写的实例方法# 看题目是不是很绕,这个我也不知道怎么才能更简单的表达了# 先看代码:public class Common {public static void main(String[] args) {Sub sub = new Sub();...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,328
精华内容 3,731
关键字:

java调用重写的方法

java 订阅