Java的一点内容(2)
1 面向对象的三个原则 封装性 封装的基本单元是类(class),类是一个抽象的逻辑结构,而类的对象是一个真实的物理实体;类的目的是封装复杂性,在类内部存在隐藏实现复杂性机制;
封装(encapsulation) 的两个好处:
模块化:可以独立于其他对象的源代码进行编写和维护,可以很容易的将对象在系统中传递;
隐藏信息:其他对象可以通过本对象的一个公共接口进行通信而不影响其他对象;
继承性 继承是一个对象获得另一个对象的属性的过程,继承机制是一个对象成为一个更具通用类的一个特定实例成为可能,避免了代码的重复编写;
多态性 (重载overload,方法名相同、参数的个数不同、参数的类型不同、返回的类型不同和覆盖override) ;多态性就是“一种接口,多种方法”,可以为一组相关的动作设计一个通用的接口,其实类的函数的重载就是一种多态的体现;
4 引入抽象编程的思想; 类的封装就是一种抽象思想Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意味着通常情况下,我们不必判定是否应该进行动态绑定—它会自动发生。
- final方法会使编译器生成更有效的代码,这也是为什么说声明为final方法能在一定程度上提高性能(效果不明显)。
- 如果某个方法是静态的,它的行为就不具有多态性:
class StaticSuper {
public static String staticGet() {
return "Base staticGet()";
} public String dynamicGet() {
return "Base dynamicGet()";
}
} class StaticSub extends StaticSuper {
public static String staticGet() {
return "Derived staticGet()";
} public String dynamicGet() {
return "Derived dynamicGet()";
}
} public class StaticPolymorphism { public static void main(String[] args) {
StaticSuper sup = new StaticSub();
System.out.println(sup.staticGet());
System.out.println(sup.dynamicGet());
} }输出:
Base staticGet()
Derived dynamicGet()
构造函数并不具有多态性,它们实际上是static方法,只不过该static声明是隐式的。因此,构造函数不能够被override。
在父类构造函数内部调用具有多态行为的函数将导致无法预测的结果,因为此时子类对象还没初始化,此时调用子类方法不会得到我们想要的结果。
class Glyph {
void draw() {
System.out.println("Glyph.draw()");
}
Glyph() {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
} class RoundGlyph extends Glyph {
private int radius = 1; RoundGlyph(int r) {
radius = r;
System.out.println("RoundGlyph.RoundGlyph(). radius = " + radius);
} void draw() {
System.out.println("RoundGlyph.draw(). radius = " + radius);
}
} public class PolyConstructors { public static void main(String[] args) {
new RoundGlyph(5); } }输出:
Glyph() before draw()
RoundGlyph.draw(). radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(). radius = 5
为什么会这样输出?这就要明确掌握Java中构造函数的调用顺序:
(1)在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制0;
(2)调用基类构造函数。从根开始递归下去,因为多态性此时调用子类覆盖后的draw()方法(要在调用RoundGlyph构造函数之前调用),由于步骤1的缘故,我们此时会发现radius的值为0;
(3)按声明顺序调用成员的初始化方法;
(4)最后调用子类的构造函数。
只有非private方法才可以被覆盖,但是还需要密切注意覆盖private方法的现象,这时虽然编译器不会报错,但是也不会按照我们所期望的来执行,即覆盖private方法对子类来说是一个新的方法而非重载方法。因此,在子类中,新方法名最好不要与基类的private方法采取同一名字(虽然没关系,但容易误解,以为能够覆盖基类的private方法)。
Java类中属性域的访问操作都由编译器解析,因此不是多态的。父类和子类的同名属性都会分配不同的存储空间,如下:
// Direct field access is determined at compile time.
class Super {
public int field = 0;
public int getField() {
return field;
}
} class Sub extends Super {
public int field = 1;
public int getField() {
return field;
}
public int getSuperField() {
return super.field;
}
} public class FieldAccess { public static void main(String[] args) {
Super sup = new Sub();
System.out.println("sup.filed = " + sup.field +
", sup.getField() = " + sup.getField());
Sub sub = new Sub();
System.out.println("sub.filed = " + sub.field +
", sub.getField() = " + sub.getField() +
", sub.getSuperField() = " + sub.getSuperField());
} }输出:
sup.filed = 0, sup.getField() = 1
sub.filed = 1, sub.getField() = 1, sub.getSuperField() = 0Sub子类实际上包含了两个称为field的域,然而在引用Sub中的field时所产生的默认域并非Super版本的field域,因此为了得到Super.field,必须显式地指明super.field。
Java的一点内容(2)的更多相关文章
- Java 创建文本内容
Java 创建文本内容 import java.io.FileWriter; import java.io.IOException; public class TestFile { public st ...
- java读取文本文件内容2
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/183 很久之前写了一篇Java读取文本文件内容,链接地址是 ...
- java读取文本文件内容
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/128 java读取文本文件内容 今天写代码写着要调试一个很 ...
- java一点内容
1.JAVA有哪些基本数据类型 String是不是基本数据类型 Java语言提供了八种基本类型: 六种数字类型(四个整数型,两个浮点型) 字节型byte 8位 短整型short 16位 整型int 3 ...
- JAVA记录-JSP内容
JSP(JavaServer Pages )是什么? JavaServer Pages(JSP)是一种支持动态内容开发的网页技术它可以帮助开发人员通过利用特殊的JSP标签,其中大部分以<%开始并 ...
- java swing文件内容检索工具
Java相关技术 - 文件内容检索工具 拿到一个几百M甚至上G的project让你去学习 有时候你会想知道某个关键词是在哪个文件里 比如:spring MVC配置的@RequestMapping,你从 ...
- Java追加文件内容的三种方法
import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io. ...
- java读取word内容
暂时只写读取word内容的方法. 依赖的jar: poi-3.9-20121203.jarpoi-ooxml-3.9-20121203.jarxmlbeans-2.3.0.jar package co ...
- API例子:用Java/JavaScript下载内容提取器
1,引言 本文讲解怎样用Java和JavaScript使用 GooSeeker API 接口下载内容提取器,这是一个示例程序.什么是内容提取器?为什么用这种方式?源自Python即时网络爬虫开源项目: ...
随机推荐
- OSG多屏显示问题
// testMultiScreen.cpp : Defines the entry point for the console application.// #include "stdaf ...
- webstrom的注释
今天我们小组的新同学有一个BUG调不好,然后我就帮他调一下.在调试的过程中非常累,纠其原因还是他注释写的不完善.我们可以看一下,他是这样写注释的(随便拿一个方法举例),如下图: 乍一看,是不是觉得他的 ...
- Python新手学习基础之数据类型——数字类型
创建一组数字 Python 的有以下几种内置数字类型: int,整型,比如:1.-2.598: float,浮点型,比如:0.0.-3.5.18.55: bool,布尔型,即True和False两个关 ...
- 原生js制作弹出框
完整代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...
- 注解 @Resource与@Autowired与@Component的使用
在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才 ...
- LeetCode_Minimum Window Substring
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- 防止DC电源反接的方法——SS14的用法
出处:http://blog.ednchina.com/tengjingshu 电源是PCB板的重要部分,每个芯片都需要电源供给.芯片其实是挺脆弱的,只要正负接反得话,大多数就会挂掉,相信很多人都有惨 ...
- C#中使用SendMessage进行进程通信的实例
原文:C#中使用SendMessage进行进程通信的实例 1 新建解决方案SendMessageSecondExample 在解决方案下面新建两个项目:Sender和Receiver,两者的输出类型均 ...
- linux tee 命令详解
man tee: NAME tee - read from standard input and write to standard output and files SYNOPSIS tee [OP ...
- USB Video Class及其实现
1 Video Class 基础概念Usb协议中,除了通用的软硬件电气接口规范等,还包含了各种各样的Class协议,用来为不同的功能定义各自的标准接口和具体的总线上的数据交互格式和内容.这些Class ...