1、对象导论
组合和继承 has-a 和 is-a
组合关系has-a | 继承关系is-a |
---|---|
代码黑盒复用,被包括的对象内部实现细节对外不可见,封装性好。 | 代码白盒复用,父类的实现细节暴露给子类,破坏了封装性 |
不破坏封装, 整体类与局部类之间松耦合,彼此相互独立。 | 破坏封装,子类与父类之间紧密耦合,子类依赖父类的实现,子类缺乏独立性 |
整体类不能自动获得和局部类同样的接口 | 子类能自动继承父类的接口。 |
整体类可以对局部类进行包装,封装局部类的接口,提供新的接口 | 子类不能改变父类的接口 |
具有较好的可扩展性 | 支持扩展,通过继承父类实现,但会使系统结构较复杂 |
每个类只专注于一项任务 | 易于修改被复用的代码 |
支持动态组合,可在运行时根据具体对象选择不同类型的局部对象(扩展性比继承好) | 不支持动态拓展,在编译期就决定了父类 |
创建整体类的对象时,需要创建所有局部类的对象。 | 创建子类的对象时,无须创建父类的对象 |
在这里插入代码片
为判断自己到底应该选用合成还是继承,一个最简单的办法就是考虑是否需要从新类上溯造型回基础类。若必须上溯,就需要继承。但如果不需要上溯造型,就应提醒自己防止继承的滥用
面向过程和面向对象
面向过程 Procedure Oriented | 面向对象 Object Oriented |
---|---|
面向过程强调的是完成既定目标需要完成哪些步骤,总结完步骤之后,把所有步骤走完也就达到了既定目标,所以一个目标就是各个步骤糅合的结果 | 面向对象强调的是完成既定目标需要哪些条件,逐步满足各个条件之后再进行组装合并,达到既定目标 |
对目标进行调整时,需重新走完整个步骤,不能根据需求变化在原来的基础上快速调整自己,缺乏灵活性 | 面向过程是面向对象的基础,面向对象尽可能避免冗余的工作 |
2、一切都是对象
Java与C++区别
尽管Java是基于C++的,但是相比之下,Java是一种更“纯粹”的面向对象程序设计语言。
Java | C++ |
---|---|
Java有垃圾回收机制,用来监视new出来的所有对象,辨别不会再被引用的对象,释放内存空间 | C++创建对象之后,需要在使用完后调用delete方法将其销毁 |
Java中一个非布尔值不能当作布尔值在逻辑表达式中使用 | C++ 逻辑表达结果值为0则为假,非0为真 |
Java同一作用域范围下的局部变量和局部变量不能重名,即局部变量不能重复定义,但是如果局部变量超出了它本身的作用范围就会失效,被JVM垃圾回收,则可以重复命名此变量; 同一作用域范围下的成员变量名和局部变量名可以相同,在方法中使用变量时,如果不指名使用成员变量还是局部变量,就默认使用局部变量(就近原则) | C和C++会将较大作用域的变量隐藏起来 |
Java中新增一种“无符号”右移位操作符( >>> ) ,无论正负,都在高位插入0 | C C++ 中没有 |
在Java中,数组定义时,int arr[]; 只定义了数组变量,数组不可以使用,只有数组初始引用指向实例后,才会创建数组 分配存储空间 并可以使用。(创建时指定数组大小) | C++中,数组定义时就已经分配存储空间,可以使用。(定义时指定数组大小) |
Java成员变量如果未被赋初始值的会被赋予一个默认初始值();局部变量未赋初始值编译器会报错提示 | C++ |
Java中goto作为保留字,在语言中并未使用它。但是Java提供了一种类似的跳转机制-标签 ( 后面跟有冒号的标识符) | C++有goto |
Java类只有单一继承,一个类可以实现多个接口,一个接口可以多继承接口 | C++ 有多继承 |
标识符命名
标识符——给类 、接口、方法、语句块、变量、常量等命名。
标识符命名规则:必须遵守,否则编译器不通过
- Java标识符由 数字 字母 下划线_ 或美元符号$ 组成;
- 不能以数字开头,不能含有空格;
- 不能是Java关键字和保留字,可以包含;
- Java区分大小写,长度无限制;
合法标识符 | 非法标识符 |
---|---|
HelloWorld, $12_salary, hiWorry, 12days , IK | #name , 12days, class, &date , if , @emi |
Java关键字和保留字
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
标识符命名规范:不遵守不影响程序运行,但要求大家遵守
- 在起名字时,不要用拼音,尽量用英文,达到“见名知意”
- 包: 全部小写,程序员在自定义包名前加上唯一的前缀(域名反转) ,中间由点 分隔开
- 类和接口名:Pascal式命名,每个单词的首字母大写。例如: MyClass,HelloWorld,Time等。
- 方法名:Camel式命名,第一个单词首字母小写,其余单词的首字母大写。尽量少用下划线。例如:getFun,method,setAgeOfBirds等。
- 构造方法名: 与类名一样
- 变量名:Camel式命名,第一个单词首字母小写,其余单词的首字母大写。尽量少用下划线,少用美元符号。
- 常量名: 基本数据类型常量名全部字母大写,字与字之间用下划线分隔。对象常量可大小写混写。
注意:Java 的null 不是关键字,类似于true 和 false ,也不允许作为标识符使用;
基本数据类型
变量就是申请内存来存储之,即当创建变量时,需要在内存中申请空间。因此,通过定义不同类型的变量,可以在内存中存储整数、小数或者字符。Java两大数据类型:基本数据类型,引用数据类型。
Java提供八种基本类型:六种数字类型(四个整数型,两个浮点型),一种字符类型,一种布尔类型。
数据类型 | 关键字 | 内存占用 | 取值范围 | 默认值 | 存储方式 | 备注 |
---|---|---|---|---|---|---|
字节型 | byte | 1个字节 | -128~127 | 0 | 有符号,以二进制补码表示 | 用在大型数组中节约空间,主要代替整数,因为byte变量占用的空间只有int类型的四分之一 |
短整型 | short | 2个字节 | -32768(-2^15)~ 32767(2^15 - 1) | 0 | 有符号 以二进制补码表示 | short数据类型也可以向byte那样节省空间 |
整型 | int (默认) | 4个字节 | -2,147,483,648(-2^31)~ 2,147,483,647(2^31 - 1) | 0 | 有符号 以二进制补码表示 | 一般的整型变量默认为int 类型 |
长整型 | long | 8个字节 | -9,223,372,036,854,775,808(-2^63)~ 9,223,372,036,854,775,807(2^63 -1) | 0L | 有符号的以二进制补码表示 | 主要使用在需要比较大整数的系统上;“L" 理论上不分大小写,为避免与数字1混淆,最好大写 |
单精度浮点数 | float | 4个字节 | -3.402823E+38 ~ 3.402823E+38 | 0.0f | 符合IEEE 754 标准 | 浮点数不能用来表示精确的值,如货币 |
双精度浮点数 | double (默认) | 8个字节 | -1.79769313486232E+308 ~ 1.79769313486232E+308 | 0.0d | 符合IEEE 754 标准 | 同样不能表示精确的值 。7 int。7D 7. 7.0 是double字面量 |
字符型 | char | 2个字节 | 0~65535 | ‘u0000’ | Unicode字符 | char数据类型可以存储任何字符 |
布尔类型 | boolean | 1个字节 | true, false | false | 只作为一种标志来记录true/false情况 |
自动类型转换:
整型,浮点型,字符型数据可以混合运算。运算中,不同类型的数据先转化为同意一类型再进行运算。转换过程中可能导致溢出或者损失精度。浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入。
低 ------------------------------------> 高 |
---|
byte,short,char—> int —> long—> float —> double |
static关键字
当声明一个事物是static时,就意味着这个域或者方法不会与包含它的那个类的任何对象关联在一起。
static修饰 | 含义 | 调用 | 应用场景 | 备注 |
---|---|---|---|---|
类- 静态内部类 | static修饰类只能修饰内部类 | ①外部类可以通过“外部类名.内部类名.属性(方法) ”直接调用静态内部类中的静态属性和方法;②外部类可以通过创建静态内部类实例对象来调用静态内部类的非静态属性和方法。(创建静态内部类实例对象:①在非本外部类中: 本外部类名.内部类名.属性(方法)obj= new 本外部类名.内部类名(); ②在外部类中:内部类名 obj = new 内部类名(); ) | 静态内部类不能访问其外部类的实例成员(包括普通的成员变量和方法),只能访问外部类的类成员(静态成员变量和静态方法);即使是静态内部类的实例方法也不能访问其外部类的实例成员 | |
方法-静态方法/类方法 | 静态成员方法属于类本身而不属于某个对象,不需要创建对象就可以调用,非静态成员方法需要通过对象来调用 | 类名.方法名 | 在静态成员方法中不能使用this, super,也不能调用非静态成员(变量或方法) | |
变量-静态变量/类属性 | 在方法区中存储,该类的所有对象共享此属性 | 类名.属性名,不推荐使用对象调用类属性 | 只要静态成员变量所在的类被加载,这个静态成员变量就会被分配内存空间;相对应的非静态成员变量属于对象,只有在内存中构建该类对象时,非静态成员变量才被分配内存空间 | |
语句块-静态代码块/静态初始化器 | 静态代码块在类加载时执行,并且只执行一次。一个类中可以编写多个静态代码块,按照自上而下的顺序执行 | static代码块不需要程序员主动调用,在JVM加载类时系统会执行static代码块 | 在static代码块中做一些类成员变量的初始化工作,所有的static代码块只能在JVM加载类时被执行一次。 |