class A {
int a = 0 ;
int b = 1 ;
}
class B extends A{
int c = 1;
double d = 2.2;
}
class C {
public int CCC(A a){
System.out.println();
return 1;
}
}
public class Test{
public static void main(String[] args) {
C c = new C();
B b = new B();
c.CCC(b);
}
}
如题,我把B(子类)引用传给CCC方法,该方法入参是B的父类A类型,这样的目的是什么? 和入参类型为B类型有什么区别?
因为现在研究一个分页的功能,它的分页信息就在B中,但是实际调DAO层方法的入参是A类,那么分页信息是如何生效的?
传入A是因为B 继承于A 那么B一定包含A的属性和方法 CCC方法需要参数是A 则认为CCC方法需要的是A中的某个属性或者方法等
但传入B意味你可以在B中进行A之外的处理 或者在B中对A的属性和方法等进行了补充或修改
如果做分页 传入参数是A 可能是在A中定义的属性或方法需要用到 需要在B中进行属性修改 或者方法重写 他使用的是修改后的数据
这不就是多态么。c在接收参数是可以接受A的任意子类型。
当子类继承了某个类之后,便可以使用父类中的成员变量,但是并不是完全继承父类的所有成员变量。具体的原则如下:
1)能够继承父类的public和protected成员变量;不能够继承父类的private成员变量;
2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;
3)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。
作为一个新手我觉得应该是继承的问题,A和B都有各自的方法,B继承了A,那么B可以引用A类中的一些方法,这就不需要在B类重复写方法了,
当然方法重写不算,建议你看一下那个基础的继承,多态,应该会有帮助。我觉得总之就一句话:为了调用父类方法,减少代码重复提高效率
当子类继承了某个类之后,便可以使用父类中的成员变量,但是并不是完全继承父类的所有成员变量。具体的原则如下:
1)能够继承父类的public和protected成员变量;不能够继承父类的private成员变量;
2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;
其实很多公司的分页控件都是以继承的方式实现的,比如
/**
@version 1.0
*/
public class Pageable extends Order{
public transient final static int FIRST_PAGE = 1;
public transient final static int DEFAULT_ROWS = 10;
/**当前页,从1开始*/
private Integer page;
/**每页返回*/
private Integer rows;
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Integer getRows() {
return rows;
}
public void setRows(Integer rows) {
this.rows = rows;
}
}
下面看一下继承的order类
/**
@version 1.0
*/
public class Order {
public transient final static String ORDER_DESC = "desc";
public transient final static String ORDER_ASC = "asc";
/**当前排序字段*/
private String sort;
/**是否升序*/
private boolean asc;
public String getSort() {
return sort;
}
public void setSort(String sort) {
this.sort = sort;
}
public void setOrder(String order) {
asc = !"desc".equals(order);
}
public String getOrder() {
return asc?"asc":"desc";
}
public boolean isAsc() {
return asc;
}
}
这里主要是为了程序的健壮性和扩展性, 目前我这里父类只定义了排序的方式, 子类才定义了分页的字段, 这些我现在的模块要用这个分页类,但是如果
以后我别的模块要用其他的分页类型,只需要重新继承order类就行了,这就是java的多态,只是为了易于扩展以及可能你们项目涉及到解耦等等。
其实方法参数用父类,就定义了一个很大的扩展性, 假设,你们项目现在用的是你举的例子中的b类, 然后如果你们项目可能以后有一个排序用的e类,
而且这个e类现在还要用在你之前写的代码中, 这个时候 你是不是还要去修改你的方法参数中的变量, 应为b类和e类是不能弄混淆的, 但是如果
b和e都继承了a, 那么如果你方法参数都是用a来定义的, 那么你子类在进行传值的时候是没有影响的
CCC方法设计为入参是父类A而不是具体的子类B ,目的就是为了满足多种可变情况,
如果你入参类型为B,你C类中用到B的地方就只能有B一种实现,
而你用A作为入参,只要是A的子类都可以传入C,那C用到A方法的地方是不是就可以有任何可能的实现了?
只要是A的子类就可以传入,不同的子类不同的实现。。
你第二个问题看起来好像你还不太理解重写,A种有invoke方法 ,B继承了A,重写了invoke方法,你再C里用到了A参数,但是你传入的是B,执行invoke方法时当然是执行的B中重写的invoke方法了
多态最基本的有两种:一是同一个方法可以有不同的实现,比如说不同的职业对于work()这个方法会有不同的实现;
另一个就是不同的对象的行为多样,类似于同一个职业的不同人每天的行为所对应的方法也有不同。
继承是最基本的多态:子类可以增加父类的行为,也可以修改父类的行为,但既然用继承,说明子类中要用到父类的成员变量和方法,即他们在行为上
有共性,首先由于向上造型的特性,子类是可以转化为父类的,所以 c.CCC(b)这个方法虽然参数是A类的对象,但由于B可以转化为A,所以传入A的子类B
是完全可以的,但这样我觉得应该类似于父类引用指向子类对象。
和直接传入B的区别是:题中方式只能调用A类中有的方法和变量,但实际的实现是子类中的代码,好处是也可以传入A的其他子类或者A,这样这个方法
就变得灵活多变;
而直接传入B是可以调用B中的所有的变量和方法,但只能传入B类。