**
JAVA基础 *
*面向对象
什么是面向对象?
对比面向过程,是两种不同的处理问题的角度
面向过程更注重事情的每一个步骤和顺序,面向对象更注重事情有哪些参与者(对象)、每个对象需要做什么。
比如:煮饭
面向过程会将任务差结成一系列的步骤(函数),1.拿出大米 2.放入电饭煲 3.煮饭 4保温
面向对象会拆出 人 和 电饭煲 两个对象。
人:拿出大米 放入电饭煲 按下煮饭按钮
电饭煲:煮饭 保温
从以上例子能看出,面向过程比较直接高效,面向对象易于复用,扩展和维护。
面向对象
封装:封装的意义,在于明确表示出允许外不适用的所有成员函数的数据项内部对外调用透明,外部调用无需修改或者关心内部实现。
1.javabean的属性私有,提供getset对外访问,因为属性的赋值或者获取逻辑只能由javabean本身决定,而不能由外部胡乱修改
private string name;
public void setName(String name){
this.name = "tuling_"+name;
}
2.orm框架
操作数据库,我们不需要关心连接如何建立的,sql是如何执行的,只需引入mybatis,调方法即可
**继承:**继承基类的方法,并作出自己的改变/或者拓展子类共性的方法或者属性直接使用父类的,而不需要自己再定义,只需要扩展自己的个性化。
**多态:**基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同,继承,方法重写,父类引用指向子类对象。
父类类型 变量名 = new 子类对象;
变量名.方法();
无法调用子类特有的功能
JDK JRE JVM
JDK: java Development Kit java 开发工具
JRE: java Runtime Enviroment java 运行的环境
JVM: java Virtual Machine java 虚拟机
==和equals比较
== 对比的是 栈 中的值,基本数据类型是变量值,引用类型是 堆 中内存对象的地址
equals: object中默认采用 == 比较,通常会被重写
Object
public boolean equals(object obj) {
return (this == obj);
}
String
public boolean equals(object anobject) {
if (this == anobject) {
return true;
}
if(anobject instanceof String) {
String anotherString = (String)anobject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = antherString.value;
int i = 0;
while (n-- !=0){
if(v1[i] != v2[i])
return false;
i++
}
return true;
}
}
return false;
}
上诉代码可以看出,String类中被腹泻的equals()方法其实比较两个字符串的内容。
public class StringDemo {
public static void main (String args[] ) {
String str1 = "Hello";
String str2 = new String("Hello");
String str3 = str2;//引用传递
System.out.println(str1 == str2);//false
System.out.println(str1 == str3);//false
System.out.println(str2 == str3);//true
System.out.println(str1.equals(str2));//true
System.out.println(str1.equals(str3));//true
System.out.println(str2.equals(str3));//true
hashCode 和 equals
hashCode()的作用是获取哈希码,也成为散列码;它实际上是返回一个int整数,这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()定义在JDK的Object.java中,java中的任何类都包含有hashCode()的函数。
散列表存储的事键值对(key-value),它的特点是:能根据“键”快速检索出对应的value.这其中就利用到了散列码!(可以快速找到所需要的对象)
为什么要有hashCode:
以“HashSet如何检查重复”为例子来说明为什么要有hashCode;
对象加入HashSet时候,HashSet会先计算对象的hashcode的值来判断对象加入的位置,看该位置是否有值,如果没有,HashSet会假设对象没有重复出现,但是如果发现有值,这时候会调用equals()方法来检查两个对象是否真的相同,如果两者相同,HashSet就不会让其加入操作成功,如果不同的话,就会重新散列到其他位置,这样就大大减少了equals的次数,相应就大大提高了执行速度。
- 如果两个对象相等,hashcode也一定是相同的
- 两个对象相等,对两个对象分别调用equals方法都返回true
- 两个对象有有相同的hashcode值,他们也不一定是相同的
- 因为,equals方法被覆盖过,则hashCode方法也必须被覆盖
- hashCode()默认行为是对堆上的对象产生独特值,如果没有重写hashCode(),该class上的两个对象无论如何都不回相等(即使这两个对象指向相同的数据)
Final 最终
- 修饰类:表示类不可被继承
- 修饰方法:表示方法不可被子类覆盖,但是可以重裁
- 修饰变量:便是变量一旦被赋值就不可以随意更改她的值
(1)修饰成员变量
- 如果 final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类变量时指定初始值
- 如果 final修饰的事成员变量,可以在非静态初始化块,声明该变量或者构造器中执行初始值
(2)修饰局部变量
系统不会为局部变量进行初始化,局部变量必须由程序员显示初始化,因此使用final修饰局部变量时候,即可以再定义时候指定默认值(后面的代码不能对变量再赋值),也可以不指定默认值,而在后面的代码中对final变量赋值(一次)
public class Finalvar{
final static int a = 0;//再声明的时候就需要赋值 或者静态代码块赋值
/**
static{
a = 0;
}
**/
final int b = 0;//再声明的时候需要赋值 或者代码中赋值 或者构造器赋值
/*{
b = 0;
}*/
public static void main(String}[] args){
final int localA; //局部变量只声明没有初始化,不会报错,与fanal无关
localA= 0;//在使用之前一定要赋值
//LocalA = 1;但是不允许第二次赋值
}
}
(3)修饰基本类型数据和引用类型数据
- 如果是基本类型的变量,则其数值一旦再初始化之后便不能更改;
- 如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个兑现个,但是引用的值是可变的
public class FinalReferenceTest{
public static void main(){
final int [] iArr ={1,2,3,4};
iArr[2] =3 ;//合法
iArr = null;//非法,对iArr不能赋值
final person p =new person(25);
p.setAge(24);//合法
p = null;//非法
为什么局部内部类和匿名内部类只能访问局部final变量?
编译之后会生成两个class文件,Test.class Test1.class
public class Test {
public static void main(String [] args) {
}
//局部final变量a,b
public void test (final int) {
final int a =10;
new Thread(){
public void run(){
System.out.println(a);
System.out.println(b);
};
};start();
}
}
class Outclass {
private int age = 12;
public boid outPrint(final int x ){
class InClass {
public void Inprint() {
System.out.println(x);
System.out.println(age);
}
}
new InClass().InPrint();
}
}
首先需要知道的一点是:内部类和外部类是处于用一个几倍的,内部类不会因为定义在方法中就会随着方法的执行完毕就被销毁。
这里就会产生的问题是:当外部类的方法结束时,局部变量就会被销毁,但是内部类对象可能还存在(只有没人再引用它的时候,才会死亡)。这里就出现一个矛盾:内部类对象访问了一个不存在的变量,为了解决这个问题,就将局部变量赋值了一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍可以访问他,实际访问的局部变量的“copy”。这样就好像延长了局部变量的声明周期。
将局部变复制为内部类的成员变量是,必须保证这两个变量是一样的,也就是如果我们在内部类中修改了成员变量,方法中的局部变量也得跟着改变,那怎么解决这个问题?
就将局部变量设置为final,对他初始化后,我就不让你再去修改这个变量,也就保证了内部类的成员变量和方法的局部变量的一致性,这实际上也是一种妥协,使得局部变量与内部类建立的拷贝保持一致。
(未完待续)