java 覆盖
作者:又见那斯
java中覆盖基于面向对象三大特征之:继承,同时又和另一特征:多态有重要的联系,本文中讨论的有关java中覆盖的一些知识,其实在写代码的时候或许不会用到,不过知道的话总会有用处。如有错误,欢迎批评指正。
1,基本的方法覆盖
java中,覆盖是指在子类中定义与父类同名且参数类型和个数都相同的方法。 如:
public class A{
public void test(int i){
System.out.println(“class A”);
}
}
public class B extends A{
public void test(int i){
System.out.println(“class B”);
}
}
子类B的test方法覆盖了父类A的test方法,因为两个方法的名字和参数都完全一样,构成覆盖.这么做的意义当然是为了在子类B中提供不同的test实现,覆盖也即是多态的基础,可以这么说,有方法覆盖就可以多态调用方法,下面的覆盖测试都是通过多态调用来测试的,如
A a=new B();则a.test(1)的结果是控制台输出:class B
2,参数相关
覆盖对于参数的有求是类型和参数个数一样,不过有两点需要注意,看有如下代码:
public class A{
public void test1(Object obj){}
public void test2(String…str){}
}
public class B extends A{
public void test1(String obj){}
public void test2(String str){}
}
请问B类中哪些方法是覆盖了父类的方法?
答案是B类中两个方法都没产生覆盖,
分析test1,父类A中要求是Object类型,而子类B中是String 类行,大家知道一个String也是一个Object,但是事实上没有产生覆盖
它们还是被认为不同的类型,不过有时能产生与覆盖相同的效果(当然这也只限于B类,不适合A类的其他子类).
分析test2,父类A中的test2采用了1.5新特性:可变长参数,在传参数这点上我认为只要把握一点,就是类型完全相同,才是覆盖。另外大家知道,可变长参数str的类型其实是String[],那么很明显String和String[]是完全不同的类型,当然不会产生覆盖。
调用测试:
A a=new B();
a.test1(“hello”);—-调用B类的test1()
a.test1(new Integer(1));—–调用A类的test1()
a.test2(“hello”);——调用A类的test2()
((B)a).test2(“hello”);—-调用B类的test2()
3,返回类型相关
大家都知道,方法覆盖是不能根据返回类型来判断的,比如:
public class A{
public int test(){}
}
public class B extends A{
public String test(){}
}
编译将不通过,因为不能通过返回类型来区别两个方法,所以就会产生重复定义的错误,即不构成重载,但也不是覆盖(下面将具体说明)。可以这么认为,编译器不允许有除重载和覆盖之外的同名和同参数的方法存在。
如果子类中方法的方法名,参数,和返回类型都完全相同,那么显而易见,构成覆盖,然而java中还有一种可以返回类型不同,又不会出错的情况就是:级联返回,
如:
public class A{
public Object test(){}
}
public class B extends A{
public String test(){}
}
这种情况是允许的,A类中test方法返回Object类型,B类中返回String,String类是Object类的子类。返回类型是父类相应方法的子类,也构成覆盖。当然这种情况更多的是出现用到泛型的时候,比如:
public class A{
public T test(){}
}
public class B extends A{
public String test(){}
}
这也一样的道理,也是方法的覆盖.
测试:
A a=new B();
a.test();—–多态调用B中的test方法
4,修饰符相关
关于修饰符,对覆盖也是有约束的,比如private方法吧能被覆盖,final方法不能被覆盖,继承时一定要覆盖父类的abstract方法。这里面也要注意几点:
如:
(1) private
public class A{
private void test(){}
public static void main(String[] args){
A a=new B();
a.test();//没有覆盖就不会多态调用,此处调用的是A类的test方法
}
}
public class B extends A{
public void test(){}
}
(2)final和abstract修饰符不能连,想想就知道,final就是不让覆盖,abstract是必须覆盖,如一起,岂不矛盾。
(3)子类中覆盖的方法的访问权限(可见度)不能比父类低,如:
public class A{
public void test(){}
}
public class B extends(){
protected void test(){}//编译出错
}
符:对synchronized关键字没有要求
5,异常相关
要求:覆盖时,子类中方法不能抛出比父类中相应方法更广泛的未检查异常。
如:
public class A{
public void test() throws FileNotFoundException{}
}
public class B extends A{
public void test() throws IOException{}/编译出错,IOException比FileNotFoundException范围广/
}
public class C extends A{
public void test() throws RuntimeException{}//可以增抛运行时异常
}
6,静态方法相关
要点:静态方法不能被覆盖,不过也要注意:
public class A{
public static void test1(){}
}
public class B extends A{
// public void test(){}//编译出错,不允许这样
public static void test(){}/可以“静态覆盖”(没这个词,只为说明问题)/
}
public class C extends A{}
调用测试:
A a=new B();
B b=new B();
a.test();—-调用A类的test()
b.test();—-调用B类的test()
A.test();—-显然的是调用A类的test();
B.test();—-调用的是B类的test();
C.test();—-还可以这么用?C类没有test()方法,但是可以这么用,调用的是A类的test(),B类中因为自己定义了test()方法,所以产生了覆盖的效果,所以”静态覆盖”还真存在。
7,属性相关
要点:类的属性是可以覆盖,但此时覆盖的同时没有多态。如
public class A{
public int i=1;
public void test(){}
}
public class B extends A{
public int i=2;
public void test(){}
}
测试:
A a=new B();
(a.i==1)=true—-即a.i是指在父类A中定义的i,不存在多态
a.test();——-调用子类B中的test(),多态
8,构造方法相关
要点:构造方法不存在覆盖一说,但可以重载。
java 覆盖的更多相关文章
- java 覆盖hashCode()深入探讨 代码演示样例
java 翻盖hashCode()深入探讨 代码演示样例 package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要 ...
- Java覆盖
Java的覆盖: 源代码: package dijia;class Parent1{ void f() { System.out.println("迪迦奥特曼1"); } void ...
- C#与Java覆盖问题
C#继承类中如含有相同的方法,避免冲突使用new关键字.在不同对象中分别对应该方法.若使用override关键字则,基类中的方法被覆盖. 如需调用非覆盖的则使用base关键字. Java中的继承类方法 ...
- 你能用Java覆盖静态方法吗?如果我在子类中创建相同的方法是编译时错误?
不,你不能在Java中覆盖静态方法,但在子类中声明一个完全相同的方法不是编译时错误,这称为隐藏在Java中的方法.你不能覆盖Java中的静态方法,因为方法覆盖基于运行时的动态绑定,静态方法在编译时使用 ...
- java覆盖和隐藏
隐藏指的是子类把父类的属性或者方法隐藏了,即将子类强制转换成父类后,调用的还是父类的属性和方法,而覆盖则指的是父类引用指向了子类对象,调用的时候会调用子类的具体方法. (1) 变量只能被隐藏(包括静态 ...
- 一个java覆盖的例子
// 覆盖class P{}class Q extends P{} class a{ static void m1(float x){ //静态方法不能被覆盖 System.out.println(& ...
- Effective Java —— 覆盖equals时总要覆盖hashCode
本文参考 本篇文章参考自<Effective Java>第三版第十一条"Always override hashCode when you override equals&quo ...
- Effective Java —— 覆盖equals时遵守通用约定
本文参考 本篇文章参考自<Effective Java>第三版第十条"Obey the general contract when overriding equals" ...
- java覆盖重写规则
重写规则之一:重写方法不能比被重写方法限制有更严格的访问级别.(但是可以更广泛,比如父类方法是包访问权限,子类的重写方法是public访问权限.) 比如:Object类有个toString()方法,开 ...
随机推荐
- 【Islands and Bridges】题解
题目 题目描述 给定一些岛屿和一些连接岛屿的桥梁,大家都知道汉密尔顿路是访问每个岛屿一次的路线,在我们这个地图中,每个岛屿有个正整数的权值,表示这个岛屿的观赏价值.假设一共有N个岛屿,用Vi表示岛屿C ...
- Linux设置程序开机自启动
注意: 作者测试时,Linux版本为RedHat6,同时应用在CentOS6应该也可以(作者未实测,但有同事在CentOS6上使用可行),系统版本的不同,可能造成操作上的差异(CentOS7就与Cen ...
- spring boot 配置HTTPS
spring boot 版本是<version>1.5.8.RELEASE</version> 1.配置文件里,看下不要有空格=[不要有空格] 2.别名 =========== ...
- 【BZOJ3811/UOJ36】 玛里苟斯
Description 魔法之龙玛里苟斯最近在为加基森拍卖师的削弱而感到伤心,于是他想了一道数学题. S 是一个可重集合,S={a1,a2,…,an}. 等概率随机取 S 的一个子集 A={ai1,… ...
- Spring Boot教程(十八)构建RESTful API
首先,回顾并详细说明一下在快速入门中使用的@Controller.@RestController.@RequestMapping注解.如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建 ...
- js,正则实现金钱格式化
https://blog.csdn.net/qq_36279445/article/details/78889305 https://github.com/jawil/blog/issues/30
- Mac securecrt 破解版安装
破解一 1.先链接:https://pan.baidu.com/s/1-1nu4eRf7BmuLg5MtlCRvw 密码:30pq 默认下载到了当前用户的”下载”目录中 在”Finder”中 ...
- IoC有什么好处
IoC(Inversion of Control):控制反转. DI(Dependency Injection):依赖注入. 控制反转是目的,依赖注入是实现控制反转的手段. 控制反转是一种面向对象的思 ...
- Spring中基于java的配置
Spring中为了减少XML配置,可以声明一个配置类类对bean进行配置,主要用到两个注解@Configuration和@bean 例子: 首先,XML中进行少量的配置来启动java配置: <? ...
- __file__, sys._getframe().f_lineno 当前文件的行号
当前文件的行号 try: f = open(sys.argv[1], "rb") address_book.ParseFromString(f.read()) f.close()e ...