1.编程基础
所谓的程序,基本上就是告诉计算机要操作的数据和执行的指令序列,即对什么数据做什么操作,比如:
1.读文档,就是将数据从磁盘加载到内存,然后输出到显示器上;
2.写文档,就是将数据从内存写回磁盘;
3.播放音乐,就是将音乐的数据加载到内存,然后写到声卡上;
4.聊天,就是从键盘接收聊天数据,放到内存,然后传给网卡,通过网络传给另一个人的网卡,再从网卡传到内存,显示在显示器上。
5.总结:基本上程序很大一部分工作就是操作内存中的数据
1.1 Java 数据类型和变量
-
整数类型:有4种整型byte/short/int/long,分别有不同的取值范围;
-
小数类型:有2种类型float/double,有不同的取值范围和精度;
-
字符类型:char,表示单个字符;
-
真假类型:boolean,表示真假。
Java是面相对象的语言,除了基本数据类型,其他都是对象类型(对象基本由基本数据类型,数组合其他对象结合而成)。 -
变量概念:为了操作数据,需要把数据放在内存中,为了方便找到和操作数据需要给这个位置起个名字。
-
变量 :表示内存中的一个位置,存放的值可以变,但含义不变
数组类型和基本类型的明显不同: -
一个基本类型变量,内存中只会有一块对应的内存空间。
-
数组有两块:一块用于存储数组内容本身,另一块存储内容的位置。
给数组中元素赋值是改变数组内容,给数组变量赋值则会让变量指向一个不同的位置。
1.2 基本运算
- 整数相除不是四舍五入,而是直接舍去小数。
比如:10/4=2而不是2.5 10/4.0=2.5 因为要按小数计算至少一个数表示为小数形式。
1.3 函数
作用:计算机程序的一种重要结构,可减少重复代码,分解复杂操作
1.3.1 栈
函数调用主要是通过栈来存储相关的数据,栈是一块内存,先进先出类似桶,主要存放函数调用过程中需要的数据,包括参数,返回地址,以及函数内定义的局部变量,
1.4 理解数据背后的二进制
image十进制 二进制 互转
29=2 x 10^1 + 9 x 10^0
image image
-
-1的补码:1的原码表示是00000001,取反是11111110,然后再加1,就是11111111
-
负数的二进制:不是简单的将最高位变为1,比如:a = -1;二进制应该是10000001,但实际,他应该是11111111. 因为负数使用的是补码表示法,因为计算机只能做加法,
-
正数的运算结果出现负数:正数最大表示01111111,即127,负数最小10000000,而计算机只能做加法,1-1其实是1+(-1)
127 01111111
1 00000001
+-------------------------
-128 10000000
看到上面就知道为啥会出现负数,因为超出范围最高位往往是1,然后会被看作负数。 -
小数计算为什么会出错:因为使用二进制,二进制不能精确表示0.1
-
char:本质上是一个固定占用两个字节的无符号正整数,这个正整数对应于Unicode编号,用于表示那个Unicode编号对应的字符。
2.类
2.1重写(Override)与重载(Overload)
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
public class Overloading {
public int test(){
System.out.println("test1");
return 1;
}
public void test(int a){
System.out.println("test2");
}
//以下两个参数类型顺序不同
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
}
2.2 类加载过程
在Java中,所谓类的加载是指将类的相关信息加载到内存。在Java中,类是动态加载的,当第一次使用这个类的时候才会加载,加载一个类时,会查看其父类是否已加载,如果没有,则会加载其父类。
寻找要执行的实例方法的时候,是从对象的实际类型信息开始查找的,找不到的时候,再查找父类类型信息。
2.2.1 内存分为栈和堆,方法区
1.堆内存用来存放由new创建的对象和数组。
2.栈内存用来存放方法或者局部变量等
3.堆是先进先出,后进后出
4.栈是后进先出,先进后出
5.存放类的信息
2.2.2 Java继承是把双刃剑
子类和父类之间可能存在实现细节的依赖,如果子类不知道把基类的实现细节,就不能正确的进行扩展。
2.2.3 怎么避免继承,有三种方法:
使用final关键字
优先使用组合而非继承
使用接口
2.2.4使用final避免继承
我们提到过final类和final方法,final方法不能被重写,final类不能被继承,我们没有解释为什么需要它们。通过上面的介绍,我们就应该能够理解其中的一些原因了。
给方法加final修饰符,父类就保留了随意修改这个方法内部实现的自由,使用这个方法的程序也可以确保其行为是符合父类声明的。
给类加final修饰符,父类就保留了随意修改这个类实现的自由,使用者也可以放心的使用它,而不用担心一个父类引用的变量,实际指向的却是一个完全不符合预期行为的子类对象。
2.2.5 优先使用组合而非继承
public class Child {
private Base base;
private long sum;
public Child(){
base = new Base();
}
public void add(int number) {
base.add(number);
sum+=number;
}
public void addAll(int[] numbers) {
base.addAll(numbers);
for(int i=0;i<numbers.length;i++){
sum+=numbers[i];
}
}
public long getSum() {
return sum;
}
}
2.2.6 接口和抽象类
- 接口更重要的是降低了耦合,提高灵活性,分解复杂问题
- 抽象类的设计目的,是代码复用。也是一种减少犯错的机制
网友评论