方法能重写,属性能重写吗?
来源:互联网 发布:程序员鼓励师慰安妇 编辑:程序博客网 时间:2024/04/27 15:51
覆写是多态的一种表现,我们平时所说的覆写一般是针对方式来说,在网上看到过有人讨论试着覆写属性,于是有点兴趣,属性真能覆写吗?回答问题之前,我们还是回忆一下方法的覆写具备哪些条件,或都说哪些方法能覆写。
先回顾一下方法覆写要注意的地方:
1、重载(也叫过载)时只与方法特征有关,但重写(覆写)是会进一步检查两个方法的返回类型是否相同、访问修饰权限是否缩小(假设public->protected方向是缩小,反之叫扩大)和抛出的异常范围是否扩大。那么什么是方式特征呢?一个方法的特征(也可叫方法签名)仅包括方法的名字、参数的个数、类型、顺序(实质上就是参数列表),而不包括方法的返回类型、访问修饰权限与所抛出的异常。
- public class A {
- public void overwrite(int i) throws IOException {}
- }
- class B extends A {
- // !! 编译通不过,不能缩小访问权限
- // void overwrite(int i) throws IOException {}
- // !! 编译通不过,不能扩大异常范围
- // public void overwrite(int i) throws Exception {}
- // 正常,编译没问题,可以不抛出异常
- // public void overwrite(int i) {}
- // 覆写父类方法
- public void overwrite(int i) throws IOException {}
- protected void overload(int i) {}
- //重载上面的方法
- int overload(long i) throws IOException {
- return 0;
- }
- }
另外,要补充说明的是重载一般是指在同一个类中多个方法间,但也可重父类的的方法,而重写只发生面父子与子类的方法间。
2、非私有非静态方法不能被任何静态方法覆写,如果子类中试着以静态方式(不管访问权限修饰符是什么)来覆写父类的方法,编译时会报错。
- public class A {
- void f() {}
- }
- class B extends A {
- // !! 编译出错,下面错误都一样
- // static void f(){};
- // private static void f(){};
- // protected static void f(){};
- // public static void f(){};
- }
3、非私有静态方法不能被任何非静态方法覆写,如果子类中试着以非静态方式(不管访问权限修饰符是什么)来覆写父类的方法,编译时会报错。
- public class A {
- public static void f() {}
- }
- class B extends A {
- // !! 编译出错,下面错误都一样
- // public void f(){}
- // protected void f() {}
- // void f() {}
- // private void f() {}
- }
4、子类与父类中有方法特征相同的静态方法时,覆写规则与非静态方法覆写规则一样,但一般我们不把静态方法的覆写叫覆写,虽然语法规则上与非静态方法相同。
- public class A {
- public static void overwrite(int i) throws IOException {
- System.out.println("父类静态方法...");
- }
- }
- class B extends A {
- // !! 编译通不过,不能缩小访问权限
- // static void overwrite(int i) throws IOException {}
- // !! 编译通不过,不能扩大异常范围
- // public static void overwrite(int i) throws Exception {}
- // 正常,编译没问题,可以不抛出异常
- // public static void overwrite(int i) {}
- // 覆写父类静态方法
- public static void overwrite(int i) throws IOException {
- System.out.println("子类静态方法...");
- }
- public static void main(String[] args) throws IOException {
- A a = new B();
- //覆写静态在语法上是合法的,但没有多态效果
- a.overwrite(0);//print: 父类静态方法...
- A.overwrite(0);//print: 父类静态方法...
- B.overwrite(0);//print: 子类静态方法...
- }
- }
上面重写了父类的静态方法,但却没有多态作用,也就是说,静态方法不存在重写这一说,只不过在语法规则上与非静态方法一样罢了。
5、私有方法对子类同名方法不产生任何影响,也就是说私有方法不能被重写,即使试着在子类覆写了父类的私有方法,不管访问权限修饰符是什么,在编译时也不会报错。原因就是私有方法对子类也是不可见的。
- public class A {
- private void f() {
- }
- // 加上static修饰符,其结果都一样
- // private static void f() {}
- }
- class B extends A {
- // 尝试每个方式,都会编译能过
- // private void f() {}
- // void f() {}
- // protected void f() {}
- // public void f() {}
- // private static void f() {}
- // static void f() {}
- // protected static void f() {}
- public static void f() {}
- }
好了,上面总结并理解方法覆后,我们再来看属性能不能覆写,其实,这是一个很无聊的问题,不像上面讨论方法那有点价值,可以说属性是没有覆写这一说的,这有点像静态方法一样,不过还是稍微看一下:
- public class A {
- // 这行不能去掉,否则①编译通不过
- int i = 1;
- A() {
- System.out.println("父类构造方法 i=" + this.i);//①
- this.f();//②
- System.out.println("父类中 " + (this == getThis()));//③ print:true
- }
- public void f() {
- System.out.println("父类方法f() i=" + this.i);
- }
- public A getThis() {
- System.out.println("父类getThis");
- return this;
- }
- }
- class B extends A {
- int i = 2;
- B() {
- System.out.println("子类构造方法 i=" + this.i);
- System.out.println("子类中 " + (this == super.getThis()));//④
- }
- public void f() {
- System.out.println("子类方法f() i=" + this.i);
- }
- public A getThis() {
- System.out.println("子类getThis");
- return this;
- }
- public static void main(String[] args) {
- /*
- * 从下面 a.i 与 b.i 的输出可以看出,某对象的属性只与声明 的类型相
- * 关,与对象本身是什么类型无关,这与方法是完全不同的
- */
- A a = new B();
- System.out.println("main方法 a.i=" + a.i);
- B b = (B) a;
- System.out.println("main方法 b.i=" + b.i);
- /*
- * output:
- 父类构造方法 i=1
- 子类方法f() i=0
- 子类getThis
- 父类中 true
- 子类构造方法 i=2
- 父类getThis
- 子类中 true
- main方法 a.i=1
- main方法 b.i=2
- */
- }
- }
这里一直有个疑问:上面①②处的this肯定都是同一个对象,且都指向子类对象,还并且与子类中this是同一象,由第③④行代码可以证明这一点。但为什么①处的this好像指向了父类对象,不然为什么①处输出的i是父类中的i呢?这说明属性除了只与定义他的类型有关外,如果在类的内部自身访问时,就会访问当前所在类的属性,与this无关,这进一步说明了属性是不具有多态这一特性的。
- 方法能重写,属性能重写吗?
- 方法能重写,属性能重写吗?
- 方法能重写,属性能重写吗?
- java中的方法能重写,属性能重写吗?
- Java中private方法能重写吗?
- java静态方法是否能重写问题
- 方法重写和方法重载的区别?方法重载能改变返回值类型吗?
- 判断是否能上大学(方法的重写,即新方法覆盖旧方法)
- IIS7 url重写后 ,重写的aspx文件能运行正常,不需要重写的html不正常
- 重写属性的set方法
- java中static方法不能被重写但是能重定义
- Swift基础语法: 30 - Swift的基类, 子类, 重写, 重写方法, 重写属性, 防止重写
- Java:方法重写 与 方法重载 与属性重写
- 不不成能 《问道》悟道体系重写战役格式
- php 禁用cookie,还能使用session,url重写
- 如果重写了service方法应该添加什么代码来保证你的doGet或doPost方法能正常执行
- IIS7 url重写后 ,重写的aspx文件能运行正常,html不正常
- 方法重写
- PowerPC VxWorks BSP分析(1)--PowerPC体系结构
- 第一个只出现一次的字符
- RandomAccessFile操作文件的例子
- vfs慢慢开始!!!
- 跨表查询 model赋值问题
- 方法能重写,属性能重写吗?
- 一些对开发有用的网址
- 基于LVS的Linux负载均衡技术实现(第一篇:基本原理)
- PXE 安装 RedHat Enterprise Linux AS 4 update 7 (linux版)
- SSD硬盘的一些想法
- oracle 用户密码md5加密
- 【转】PowerPC VxWorks BSP分析(2)--PowerPC汇编
- Django 学习笔记(3)
- 中国软件技术大会企业架构总结