面向对象:
1. 三大特性
封装性 对外部不可见。可以保护程序中的某些程序
继承性 扩展功能
多态性 方法的重载 对象是多态性
2.对象是保存在栈内存之中的,属性保存在堆内存中的。
在程序中的所有的方法是保存在全局代码区中的,此区中的内容是所有的对象共享的。
在使用对象的时候,对象必须被实例化之后对能被使用。(实例化对象并不是单单指的
是通过new关键字实现的,只要其有堆内存的空间指向,则就表示实例化成功。)
在引用操作中,如果一个对象没有堆内存的引用,而调用了类中的属性或方法,就会出现
错误。java.lang.NullPointerException.
3 .所谓引用数据类型,实际上传送的就是堆内存的使用权,可以同时为一个堆内存空间定义多个栈内存的引用操作。
4 声明对象时是不去调用构造方法的。实例化对象时才去调用构造方法。
5 所谓的匿名对象就是比之前的对象少了一个栈内存的引用关系、
6 String 的比较
public static void main(String[[ args){
String str1 = "hello";
String str2 = new String("hello");
String str3 = str2;
System.out.println("str1 == str2 ---->" + (str1 == str2)); //false
System.out.println("str1 == str3 ---->" + (str1 == str3)); //false
System.out.println("str2 == str3 ---->" + (str2 == str3)); //trues
}
现在在=== 的判断的是地址空间是否相等。判断的是地址。
7.String 的两种实例化方式
String name = "hello";
String name = new String("hellow");
字符串其实就是String类的匿名对象。
public static void main(String[] args){
System.out.println("hello".equals("hello"));
}
其实 String name = "hello";
就是表示在一个常量池中初始化一个字符串对象的指向给了栈内存空间。
只有掌握了这一点之后才可以分析出使用那种实例化方式更合适。看举例:
public static void main(String[[ args){
String str1 = "hello"; //直接赋值
String str2 = "hello"; //直接赋值
String str3 = "hello"; //直接赋值
System.out.println("str1 == str2 ---->" + (str1 == str2)); //true
System.out.println("str1 == str3 ---->" + (str1 == str3)); //true
System.out.println("str2 == str3 ---->" + (str2 == str3)); //true
}
以上三个对象的内存地址都一样的。
原因:使用直接赋值的方式。在赋值之前。程序会先在内存中常量池去寻找有没有一个的字符。 如果有的话, 则是直接内存空间去赋值另外一个对象。
如果没有,则是去开辟空间。所以使用用直接赋值的方式可以去节省内存。在使用new String() 则是每次都去开辟两个内存空间,然后再去释放第一个。
两个内存空间是应为"abc"也是一个匿名对象,那么就也会去在常量池中新建个对象。然后在去内存中赋值,完了在去给常量池中的去删除。
如:
String str = new String("hello");
分析: 首先,字符串"hello" 是String 的匿名对象。则会先在常量池中去开辟一个空间。然后,又用New 去开辟一个新的内存空间。那么先前的匿名对象的内存空间,就会被垃圾回收机制去回收。 这就是为什么说的用new String会去要开辟两个空间。使用直接赋值的方式只需要一个实例化对象即可。而使用New String() 的方式则是意味着要去开辟两个内存空间。开发中最好去使用直接赋值的方式去开发。
8 .字符串的内容一量声明则不可改变。
public static void main(String[] args){
String str = "hello "; // 开辟空间
str = str + "world" ; // “world” 匿名对象开辟空间
System.out.println("str = " + str); // "hello world" 再去开辟新的空间 .断掉str 到hello的指向,
// 然后将str指向hello world.
}
// 最后去回收了 hello 和 world 的空间。
public static void main(String[] args){
String str1 = "LiXinghua";
for(int i = 0 ; i < 100 ; i ++){
str1 + = i;
}
System.out.println(str1);
}
这样的操作要str1 断开-链接 引用100次才能去实现。性能很低。
如果一定要去使用的话。应该去使用StringBuffer类。专门去完成这样的功能。
9 .this 关键字
1) 表示类中的属性
public Person(String name,int age){ // 通过构造方法赋值
this.name = name ; // 为类中的name属性赋值
this.age = age ;// 为类中的age属性赋值
}
2 )使用this调用构造方法:如果在一个类中有多个构造方法,可以用this互相调用。
private String name ; // 姓名
private int age ; // 年龄
public Person(){ // 无参构造
System.out.println("新对象实例化") ;
}
public Person(String name){
this.name = name ;
this() ;// 调用本类中的无参构造方法
}
public Person(String name,int age){ // 通过构造方法赋值
this(name) ;// 调用有一个参数的构造方法
this.age = age ;// 为类中的age属性赋值
}
public String getInfo(){ // 取得信息的方法\
this() ;// 调用本类中的无参构造方法
return "姓名:" + name + ",年龄:" + age ;
}
注意点
1) this()调用构造方法的语句只能出现在构造方法的首行。
2)在使用this 调用本类中的其它构造方法的时候。至少有一个构造方法是不用this调用的。
3)使用this表示当前的对象。
当前对象:当前正在调用方法的对象。
class Person{ // 定义Person类
public String getInfo(){ // 取得信息的方法
System.out.println("Person类 --> " + this) ; // 直接打印this
return null ; // 为了保证语法正确,返回null
}
};
public class ThisDemo06{
public static void main(String args[]){
Person per1 = new Person() ; // 调用构造实例化对象
Person per2 = new Person() ; // 调用构造实例化对象
System.out.println("MAIN方法 --> " + per1) ; // 直接打印对象
per1.getInfo() ; // 当前调用getInfo()方法的对象是per1
System.out.println("MAIN方法 --> " + per2) ; // 直接打印对象
per2.getInfo() ; // 当前调用getInfo()方法的对象是per2
}
};
4 Static 关键字:如果现在希望一个属性被所有的对象所共同拥有,则可将其声明为static类型。
声明为 static 类型的属性或方法之后称为类属性或类方法。可由类名直接调用。
1 )使用static 声明属性
每个对象拥有各自的堆栈空间。堆内存中保存每个对象的各自的属性。但是static
属性保存在了全局数据区中。所有的对象指向全局数据区中的一个内容。所以当一
个对象修改之后,所有对象的内容将全部变化。
java中的内存区域
1)) 栈内存:可以保存对象的名称(保存访问的堆内存的地址)
2))堆内存:保存每个对象的具体属性。
3))全局代码区: 保存static类型的属性
4))全局代码区: 保存所有方法的定义:
一般的调用 static 属性的时候最好是使用类名称直接去调用。采用“类名。属性”的形式:
2 )使用static 声明方法
一个方法使用了static 去声明 ,则此方法可以直接去用类名去调用。
注意点: 使用static 方法,不能调用非static的属性或方法。
5 .对象数组
对象数组的每个元素都需要单去实例化。
Stuend[] stu = new Student[100];
for(int i = 0 ; i < stu.length ; i ++){
stt[i] = new Student();
}
6 .内部类
1) 在一个类的内部还存在一个类为同内部类。
2 )在外部去访问内部类。举例:
第一种方法:
class Outer{ // 定义外部类
private String info = "hello world" ; // 定义外部类的私有属性
class Inner{ // 定义内部类
public void print(){ // 定义内部类的方法
System.out.println(info) ; // 直接访问外部类的私有属性
}
};
public void fun(){ // 定义外部类的方法
new Inner().print() ; // 通过内部类的实例化对象调用方法
}
};
public class InnerClassDemo04{
public static void main(String args[]){
Outer out = new Outer() ; // 外部类实例化对象
Outer.Inner in = out.new Inner() ; // 实例化内部类对象
in.print() ; // 调用内部类的方法
}
};
第二种方法: 将内部类声明为静态类
class Outer{ // 定义外部类
private static String info = "hello world" ; // 定义外部类的私有属性
static class Inner{ // 使用static定义内部类为外部类
public void print(){ // 定义内部类的方法
System.out.println(info) ; // 直接访问外部类的私有属性
}
};
public void fun(){ // 定义外部类的方法
new Inner().print() ; // 通过内部类的实例化对象调用方法
}
};
public class InnerClassDemo03{
public static void main(String args[]){
new Outer.Inner().print() ; // 调用外部类的fun()方法
}
};
使用static 的内部类将是外部类。
3。 在方法中去定义内部类:
一个内部类可以在任何的位置去定义.