学习笔记2——对象初始化和面向对象特性
1.java类的初始化顺序:
(1).在一个类中,初始化顺序由变量在类中的声明定义顺序决定,成员变量(非set方法和构造方法的初始化)的初始化发生在方法调用之前,包括构造方法。
(2).静态变量在整个存储区只保留一份拷贝,本地变量不能使用静态关键字,基本类型的静态变量不需要初始化,它会根据类型获得初始化值,引用类型的静态变量默认初始化为null。
静态变量的初始化发生在需要使用的时候,一旦被初始化之后,静态变量就不会再初始化。
(3).静态初始化块和静态变量类似的执行也在构造方法之前,并且仅执行一次。
(4).动态初始化块(与静态初始化块类似,只是没有static关键字,即放在一对大括号中的代码块)在静态初始化块初始化结束后执行,动态初始化块每次创建新对象都会初始化一次。
(5).构造方法执行时,先执行父类的构造方法,后执行子类的构造方法。
(6).本地变量初始化最晚,在方法中初始化。
综述,类的初始化顺序依次为:
a.父类的静态变量/静态初始化块;
b.子类类的静态变量/静态初始化块;
c.父类的动态初始化块、非构造方法和set方法的成员变量初始化
d.子类的动态初始化块、非构造方法和set方法的成员变量初始化
e.父类的构造方法。
f.子类的构造方法。
g.父类本地变量。
h.子类的本地变量。
2.数组初始化:
Java中数组初始化有以下3中方式:
(1).数组声明时直接初始化,如:
int[] a = {1,2,3};
(2).动态数组初始化,如:
int[] a = new int[]{1,2,3};
注意:动态数组初始化时,不能在new()操作符中指定数组的大小,即int[] a = new int[3]{1,2,3}的写法是错误的,数组的大小由初始化数组元素个数决定。
(3).固定长度数组初始化,如:
int[] a = new int[3];
a[1] = 0;
a[2] = 1;
a[3] = 2;
注意:固定长度大小的数组初始化时不能大于所声明的数组长度,没有声明的数组元素使用其默认值,如int默认为0,对象类型的值为引用,默认为null.
3.java代码重用4中方式:
java面向对象编程中提供了如下4中代码重用的方式:
(1).组合:
面向对象编程中最常用的代码复用方式,具体的方式是在一个对象中将另一个对象引用最为成员变量,其最大的优点是既实现松散耦合,有可能提高代码复用率。
(2).继承:
面向对象编程中常用的提高代码复用率的方法之一,适用于子类和父类是同一种抽象类型,具有共同的属性情况。
使用继承,子类可以复用父类除private私有房屋控制权限以为的所有属性和方法,编译器将父类封装为子类对象内部的一个对象。
需要注意的是:调用子类初始化构造方法时,编译器会确保首先调用父类的构造方法初始化父类,然后才初始化子类,如果父类中没有默认的构造方法,即需要显式传入参数的构造方法时,子类必须通过super关键字显式传入参数调用父类的构造方法。
(3).委派:
Java中不支持委派方式的代码复用,但是开发人员可以使用委派机制实现代码的重用。
委派是指,java对象的所有方法其实都是委派调用另一个类的方法实现,但是当前类又不是所委派类的类型,因此使用继承不太合适,解决方式和组合类似,将被委派类作为委派类的成员变量,委派类的方法直接调用被委派类对象应用的方法。
如:
- //委派类
- public Class A{
- //被委派类
- private B b = new Class B();
- public void method1(){
- b.method1();
- }
- public void method2(){
- b.method2();
- }
- ……
- }
(4).联合使用组合和继承方式:
因为java中不允许多继承,如果某种情况下,一个java类需要使用多个其他类功能,且该类和其中某个类具有很多共同属性,即可以看作同一类,则可以使当前类继承具体共同属性的类,同时将其他类作为成员变量组合引用。
4.组合和继承的区别:
组合和继承都可以复用代码,很多java程序员,甚至是架构师都分不清楚什么情况下该使用组合,什么情况下应该使用继承,具体的区别如下:
(1).组合:
组合通常是在一个类中想使用另一个类已有的特性,但是却不想使用其接口。
使用组合可以可以将一个类作为当前类的内嵌对象,这样在当前类中就可以显式地使用内嵌类已经实现的功能,与此同时又不会影响当前类的调用接口。
(2).继承:
继承是隐式地使用被继承类的功能,相当于提供了一个新版本的父类实现。
使用继承,子类不但可以复用父类的功能,同时还复用了父类的接口,子类和父类的对外调用接口相同的情况下适合使用继承。
使用继承时,很多情况下需要向上类型转换,即将子类看作其父类。在编程时到底选用组合方式还是继承方式,一个简单的判断依据是:是否需要向上类型转换,如果需要就使用继承,如果不需要,则选择组合。
5.final方法:
Java中使用final类型的方法有以下两种原因:
(1).设计原因:
final类型的方法不允许其子类修改方法,即不允许子类覆盖父类的final方法。
(2).效率原因:
在早期的java实现中,如果方法被声明为final,编译器将final方法调用编译为内联调用。
正常的方法调用是:如果方法调用时,将当前的方法上下文保持到栈中,调用被调用的方法,然后在将调用上下文出栈恢复调用现场。
内联调用是:如果方法调用时,将被调用方法体拷贝到当前调用的地方合并成一个方法体,这样就避免因需要保存方法调用线程而进行的进栈和出栈操作,可以提高效率。
新版的使用hotspot技术的java虚拟机可以探测方法调用情况而做效率优化,final方法不再作为提高效率的手段,唯一的作用是确保方法不被子类覆盖。
注意:任何private的方法都是隐式的final类型,同final方法类似,private方法不能被子类所覆盖,但是private比final更严格,基类的private方法对子类不可见,private方法不再是接口的一部分。
6.多态性:
面向对象编程中的多态和继承往往是一起发挥作用的,使用继承,所有的子类和父类使用相同的对外接口,而多态的基础是晚绑定或动态绑定或运行时绑定,即对象引用使用基类类型,在编译时编译器无法确切知道到底调用哪一个具体类,只有在运行时,java虚拟机才通过类型检查确定调用对象的具体类型。
Java中默认对象引用全部是晚绑定,只有static和final类型的引用时早绑定或编译时绑定。
多态的优势是:程序的可扩张性好,无论添加多少个子类,基类的接口都不用改变,只需要在子类对应方法中提供具体实现即可,也就是所谓的将程序变化的部分和程序保持不变的部分分离。
注意:只有正常的方法可以使用多态,字段和静态方法没有多态机制。
构造方法也不支持多态机制,构造方法是隐式的static声明。
学习笔记2——对象初始化和面向对象特性相关推荐
- 【Java】Java学习笔记(2)——Java面向对象基础作业函数题
本人私人博客:Megalomania,大部分文章会现在博客上传,有不足之处欢迎指正. 学校小学期Java课程的练习题,留个档便于以后需要时候有例子可以回忆,写的烂的地方请多多包含 1.求两个数值之和 ...
- Python学习笔记(十九)面向对象 - 继承
Python学习笔记(十九)面向对象 - 继承 一.继承的概念 # 继承:子类继承父类的所有方法和属性# 1. 子类 class A(object):def __init__(self):self.n ...
- JavaScript学习笔记之对象及继承
JavaScript学习笔记之对象及继承 对象属性 ES5中有两种属性,数据属性和访问器属性. 数据属性包括[[writable]](能否修改属性的值).[[value]]等等: 访问器属性包括[[C ...
- JavaScript学习笔记:对象
JavaScript学习笔记:对象 1.声明对象 (1)字面量对象 <!DOCTYPE html> <html lang="en"> <head> ...
- es6学习笔记-顶层对象_v1.0_byKL
es6学习笔记-顶层对象_v1.0 (虽然是笔记,但是基本是抄了一次ruan大师的文章了) 顶层对象 顶层对象,在浏览器环境指的是window对象,在Node指的是global对象. ES5之中,顶层 ...
- 重学前端-学习笔记-JavaScript对象
说明 重学前端是程劭非(winter)在极客时间开的一个专栏,在此主要整理我的学习笔记.如有侵权,请联系我,谢谢. javascript对象特征 对象具有唯一标识性:完全相同的两个对象,也不是同一个对 ...
- 【java】java学习笔记之java oop(面向对象)
如下图所示为笔者总结的java oop(面向对象)学习笔记,其中,附带有代码示例(未展开),方便理解记忆.需要源文件的请到我的资源中下载,下载地址:https://download.csdn.net/ ...
- JavaScript学习笔记(十一):面向对象编程
一.关于面向对象 编程可以分为面向过程编程和面向对象编程 面向过程:就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用 面向对象:把一件事分解成一个个对象 ...
- Linux从头开始学--学习笔记6--系统初始化,内存,swap,oom,网络和网络接口
这是我从头开始学习Linux的学习笔记,后续还会更新. 记录自己的技术成长,也希望和大家分享交流,欢迎关注~ 本笔记为coursera网站课程<Linux for Developers>的 ...
最新文章
- java线程概念_《Java基础知识》Java线程的概念
- C语言 满分代码:L1-043 阅览室 (20分)(解题报告)
- SAP CRM Opportunity订单的文档流Document Flow的一些变体variant
- Spring框架教程集合
- win10 dcom服务器进程占用cpu,WIN10CPU百分百,Windows10 DCOM占用过高解决办法 | 帮助信息-动天数据...
- Android 修改actionbar标题的颜色和背景色
- linux环境手动编译安装Nginx实践过程 附异常解决
- .net站点配置完后常见报错及解决措施
- linux下Jdk版本切换
- Wingdings特殊字符及符号对照表
- 【转载】大学生必备软件免费自学视频教程,让那些培训班都见鬼去吧
- 计算机桌面动态壁纸,动态桌面壁纸,详细教您电脑动态桌面壁纸怎么设置
- 【文件类型转换】.mat后缀文件 转化为 .xml后缀文件
- Word中的手动换行符
- 数商云电子元器件B2B商城系统
- 在GitHub Students Developer Pack申请DigitalOcean的50刀优惠码
- 百忙之中抽空看了下最近几个月问的比较多的问题(为了不让一些朋友继续走弯路)...
- kernel 选项详解(stlinux2.3)
- selenium处理富文本框
- DCMTK读取dicom图像
热门文章
- 【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | Android 端实现 BasicMessageChannel 通信 )
- 【Flutter】Dart 数据类型 Map 类型 ( 创建 Map 集合 | 初始化 Map 集合 | 遍历 Map 集合 )
- 【Android 安全】DEX 加密 ( DEX 加密原理 | DEX 加密简介 | APK 文件分析 | DEX 分割 )
- 【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程
- python 在内网windows环境下pip三方包
- MySQL 快速入门教程
- Perl的输出:print、say和printf、sprintf
- 第20条:为私有方法名加前缀
- 《C程序设计语言》- 字符输入和输出
- C语言关键字--volatile(不稳定的,反复无常的)