java基础篇--02<对类的操作>
2016-01-22 14:18
423 查看
普通类
在一个继承树体系中,要初始化一个类,会同时初始化该类的所有父类(注意:这里要区分类的初始化和实例化)
初始化可以理解为类的加载(第一次使用该类会被加载);实例化一般会伴随产生实例化对象
java存储:
1》桟:存储速度仅次于寄存器(较快),主要用来存储对象的引用和方法体中的局部变量,因为方法存在的时间很短,发在桟中有利于进行快速的存取运算;(这个的生存周期是在编译期间就已经确定的)
2》堆:桟中的引用所指向的对象就是存储在堆上,还有一些就是在这个对象里的类的成员变量,较桟的存取速度较慢;(他的管理是交给java的垃圾回收机制)
java类中的this准则:在方法中谁调用就指向谁;在构造中指向类自己
java中方法的不能独立存在,只能属于类或者类的对象;
执行方法”必须”用对象或者是类;
有种形参可变的方法,例:
1》voidtest(inta,String
... books){};等价于
2》voidtest(inta,String
[] books){};
调用1》的话,可以这样
so,等价于一个String数组
注意一个方法中最多只能有一个形参可变的;
方法重载:形参不同即可,但是不能拿返回值作为鉴别,因为在调用一个函数的时候,它的返回值是可以隐藏的;
下面的例子可以看出,父类的类变量在子类的每个实例中都有一个“副本”
java中有个叫代码块的东西,使用{}框起来的代码,会在构造函数之前被调用,多个代码块按照排列顺序执行,都执行完了轮到构造函数;
这里添加一个,实例化一个类,他所调用的代码顺序
在第一次实例化一个类的时候,需要加载它的类
1》加载类的时候会在堆上给类和类的静态变量(类变量)分配空间
2》实例化对象,会在堆上给类的对象分配空间,对象中含有一些成员变量,但不包含类变量(因为它在加载的时候就完成了)
3》1和2是在堆中的两个部分,1是Name类存储的地方,它会有一个action的存储空间
2是name对象存储的地方,它有一个age存储的空间
注意:这里的“22”,“jump”之类的字串在堆中又占着自己的一块地方,并不在1和2内,而1,2内中的action和age中存储的所谓的值,只是这两个字串的指向;
图示如下:
![](https://img-blog.csdn.net/20160126144427142?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
局部变量(一种一般在方法里面定义的变量),在定义的时候并没有为其分配内存,直到初始化的时候jvm才会为其分配(且是分配在方法的桟内存中的);
堆中的资源若无指向,就会释放,因为是垃圾回收机制在管理;
桟中的资源往往随方法或者代码块的执行完毕而结束,因为是JVM在管理(编译时期就已确定);
综上;可以通过少定义或使用类的成员变量,来加快程序的运行速度,更多的是使用局部变量;
调用类的成员变量会要去到堆中抓取数据,慢!
理解封装:可以限制对“自己”的数据的不合理或者你不想看到访问;方法也是需要“封装”,即尽量通过参数传递来降低与其他方法的耦合,这样在处理大型的app就要好调整
讨论下修饰符:
1》private只能自己用
2》default自己,同包
3》protected自己,同包,不同包的子类
4》public公共(人如其名)
编写程序建议:
分模块编写,尽量不允许其他模块直接访问本模块的数据,尽量少爆露方法给外部模块使用,尽量将功能实现细节“浓缩”在本模块内;综述,一切都是为了降低耦合
在构造器执行之前,其实系统就已经创建好了一个对象,并对其的成员变量进行了默认的初始化,只是当前不能被外部访问,只能在构造器中使用“this“进行访问,直到构造器执行完毕,会返回一个指向该对象的引用,至此,可以被外部访问;
一个类可以有多个构造器,用于不同的场合,可能不同的构造器之间会有代码的重复,这就造成的在构造器中调用构造器的现象(节约代码);规则:B完全包含A,则调用A;
注意”重写”和“重载”的区别,前者覆盖原有,后者多态(凭借参数不同);
在子类中调用super可以去修改父类中的数据,因为其实父类的普通成员变量是“打包”在test对象实体一起的,即:每个test实例化对象有自己都有的super.a,test对象将他括在自己的存储里拉
可以看见,Test继承In,重写In的eat(),
1》这时候new一个Test(子类对象),访问tx的eat()和a成员变量值为Test(子类自己的东西)
2》将tx(子类对象)强制转化成In(父类对象),再访问eat()和a成员变量值,eat()为tx(子类)的,
a的值却是In(父类)的
objStrinstanceof String强制类型转换之前检查objStr这个对象能否转化成String这个类型
包装类(Integer)可以拿来和数值直接进行比较,效果相当于直接取出包装类所包装的数值进行比较,而两个包装类比较,只有里面存的指向同一个对象才会相同。可以把数值直接赋值给包装类
java特有的常量池,能保证相同的字符串直接量只有一个,不会产生多个副本;(对象池—针对包装类存在from-128
to 127才能使用对象池)
final修饰的成员变量jvm不会对其进行隐式的赋值,需要程序员手动来进行初始化;
如果final修饰的变量编译时的值已确定,那么接下来在程序中使用到的地方都会被“宏替换”,这节约了运行的成本;
抽象类和接口
===============================
抽象类的抽象方法虽然可以通过普通类的空方法来实现,但是写成抽象类算是对读者的一种提醒;另外使用抽象类也可以很好的管理子类设计的随意性,因为子类必需实现父类提供的所用抽象方法;
接口中不可以定义static方法;
内部类可以用外部类private修饰的,但是外部类不能使用内部类的东西,因为,newwai()一个外部类调用外部类的方法,而这个方法调用的内部类的方法(这时候内部类还没有实例化,就会造成问题);
1》要调用内部类的构造函数只能通过外部类的实例化
2》调用super()父类的构造器即内部类的构造器
在一个继承树体系中,要初始化一个类,会同时初始化该类的所有父类(注意:这里要区分类的初始化和实例化)
初始化可以理解为类的加载(第一次使用该类会被加载);实例化一般会伴随产生实例化对象
java存储:
1》桟:存储速度仅次于寄存器(较快),主要用来存储对象的引用和方法体中的局部变量,因为方法存在的时间很短,发在桟中有利于进行快速的存取运算;(这个的生存周期是在编译期间就已经确定的)
2》堆:桟中的引用所指向的对象就是存储在堆上,还有一些就是在这个对象里的类的成员变量,较桟的存取速度较慢;(他的管理是交给java的垃圾回收机制)
java类中的this准则:在方法中谁调用就指向谁;在构造中指向类自己
java中方法的不能独立存在,只能属于类或者类的对象;
执行方法”必须”用对象或者是类;
有种形参可变的方法,例:
1》voidtest(inta,String
... books){};等价于
2》voidtest(inta,String
[] books){};
调用1》的话,可以这样
int a = 0; String s1 = "1"; String s2 = "2"; String s3 = "3"; test(a,s1); test(a,s1,s2); test(a,s1,s2,s3);
so,等价于一个String数组
注意一个方法中最多只能有一个形参可变的;
方法重载:形参不同即可,但是不能拿返回值作为鉴别,因为在调用一个函数的时候,它的返回值是可以隐藏的;
下面的例子可以看出,父类的类变量在子类的每个实例中都有一个“副本”
class Father{ int a = 5; } class Child extends Father{ private String name = "child"; Child(String name,int a){ this.name = name; if(a!=0 ){ super.a = a; } } void print(){ System.out.println(name+" a = "+ a); } } public class Test{ public static void main(String[] args) { Child c1 = new Child("c1", 0); c1.print(); Child c2 = new Child("c2", 10); c2.print(); Child c3 = new Child("c3", 0); c3.print(); } } //result //c1 a = 5 //c2 a = 10 //c3 a = 5
java中有个叫代码块的东西,使用{}框起来的代码,会在构造函数之前被调用,多个代码块按照排列顺序执行,都执行完了轮到构造函数;
这里添加一个,实例化一个类,他所调用的代码顺序
public class Test{ public static void main(String[] args) { Child c = new Child(); } } class Father{ public Father() { System.out.println("父类构造函数"); } { System.out.println("父类代码块"); } static { System.out.println("父类静态代码块"); } } class Child extends Father{ public Child() { System.out.println("子类构造函数"); } { System.out.println("子类代码块"); } static { System.out.println("子类静态代码块"); } } 结果 ========= 父类静态代码块 子类静态代码块 父类代码块 父类构造函数 子类代码块 子类构造函数
在第一次实例化一个类的时候,需要加载它的类
class Name{ static String action= "jump"; private String age= "22"; } Name name= new Name();
1》加载类的时候会在堆上给类和类的静态变量(类变量)分配空间
2》实例化对象,会在堆上给类的对象分配空间,对象中含有一些成员变量,但不包含类变量(因为它在加载的时候就完成了)
3》1和2是在堆中的两个部分,1是Name类存储的地方,它会有一个action的存储空间
2是name对象存储的地方,它有一个age存储的空间
注意:这里的“22”,“jump”之类的字串在堆中又占着自己的一块地方,并不在1和2内,而1,2内中的action和age中存储的所谓的值,只是这两个字串的指向;
图示如下:
局部变量(一种一般在方法里面定义的变量),在定义的时候并没有为其分配内存,直到初始化的时候jvm才会为其分配(且是分配在方法的桟内存中的);
堆中的资源若无指向,就会释放,因为是垃圾回收机制在管理;
桟中的资源往往随方法或者代码块的执行完毕而结束,因为是JVM在管理(编译时期就已确定);
综上;可以通过少定义或使用类的成员变量,来加快程序的运行速度,更多的是使用局部变量;
调用类的成员变量会要去到堆中抓取数据,慢!
理解封装:可以限制对“自己”的数据的不合理或者你不想看到访问;方法也是需要“封装”,即尽量通过参数传递来降低与其他方法的耦合,这样在处理大型的app就要好调整
讨论下修饰符:
1》private只能自己用
2》default自己,同包
3》protected自己,同包,不同包的子类
4》public公共(人如其名)
编写程序建议:
分模块编写,尽量不允许其他模块直接访问本模块的数据,尽量少爆露方法给外部模块使用,尽量将功能实现细节“浓缩”在本模块内;综述,一切都是为了降低耦合
在构造器执行之前,其实系统就已经创建好了一个对象,并对其的成员变量进行了默认的初始化,只是当前不能被外部访问,只能在构造器中使用“this“进行访问,直到构造器执行完毕,会返回一个指向该对象的引用,至此,可以被外部访问;
一个类可以有多个构造器,用于不同的场合,可能不同的构造器之间会有代码的重复,这就造成的在构造器中调用构造器的现象(节约代码);规则:B完全包含A,则调用A;
注意”重写”和“重载”的区别,前者覆盖原有,后者多态(凭借参数不同);
class In { public int a = 5; } public class Test extends In { public static void main(String[] args) throws IOException { Test tx = new Test(); tx.print(); } public Test() { super.a = 9; } void print() { System.out.println(super.a); } }
在子类中调用super可以去修改父类中的数据,因为其实父类的普通成员变量是“打包”在test对象实体一起的,即:每个test实例化对象有自己都有的super.a,test对象将他括在自己的存储里拉
class In { public int a = 5; public void eat() { // TODO Auto-generated method stub System.out.println("father eat"); } } public class Test extends In{ public int a = 1; public sta e4b8 tic void main(String[] args) throws IOException { Test tx = new Test(); tx.eat(); In in = (In)tx; System.out.println(tx.a); in.eat(); System.out.println(in.a); } public void eat() { // TODO Auto-generated method stub System.out.println("child eat"); } void print(){ System.out.println(super.a); } }
可以看见,Test继承In,重写In的eat(),
1》这时候new一个Test(子类对象),访问tx的eat()和a成员变量值为Test(子类自己的东西)
2》将tx(子类对象)强制转化成In(父类对象),再访问eat()和a成员变量值,eat()为tx(子类)的,
a的值却是In(父类)的
objStrinstanceof String强制类型转换之前检查objStr这个对象能否转化成String这个类型
包装类(Integer)可以拿来和数值直接进行比较,效果相当于直接取出包装类所包装的数值进行比较,而两个包装类比较,只有里面存的指向同一个对象才会相同。可以把数值直接赋值给包装类
java特有的常量池,能保证相同的字符串直接量只有一个,不会产生多个副本;(对象池—针对包装类存在from-128
to 127才能使用对象池)
final修饰的成员变量jvm不会对其进行隐式的赋值,需要程序员手动来进行初始化;
如果final修饰的变量编译时的值已确定,那么接下来在程序中使用到的地方都会被“宏替换”,这节约了运行的成本;
抽象类和接口
===============================
抽象类的抽象方法虽然可以通过普通类的空方法来实现,但是写成抽象类算是对读者的一种提醒;另外使用抽象类也可以很好的管理子类设计的随意性,因为子类必需实现父类提供的所用抽象方法;
接口中不可以定义static方法;
内部类可以用外部类private修饰的,但是外部类不能使用内部类的东西,因为,newwai()一个外部类调用外部类的方法,而这个方法调用的内部类的方法(这时候内部类还没有实例化,就会造成问题);
class Out{ class In{ public In(){ } } } public class Test extends Out.In{ public Test(Out out){ out.super(); } }
1》要调用内部类的构造函数只能通过外部类的实例化
2》调用super()父类的构造器即内部类的构造器
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树