这几天学的内容真是很有料,Java这门语言的核心设计思想,开始慢慢揭开面纱。
话说回来,这两天在看《疯狂Java讲义》的时候,偶尔会对一些问题产生疑惑,而这时候我重新拿起了《Thinking in Java》,我发现这本书现在对我来说,当作一本参考式的资料还是非常不错的,因为里面的内容,真的太丰富了,而且原理级的内容也讲的很到位,打算看完《疯狂》,再把《Thinking in Java》过一遍。
static关键字:
好吧,先说为什么会出现这样的东西。我们说,在描述一个类与其对象的关系的时候,因为对象是类的具体化,所以对象对于的变量应该具有具体的值。而也正是一个个具体的参数,构成类一个具象的对象。但是如果这些对象都拥有一共性呢?这个共性拿什么描述?比如说一个Person类,其中小王很高,小李很矮,但他二人都只有两双眼睛,两只手,都会说话。这样的话,我们就应该把这些共性,也就是作为一个Person都会有的属性,用static来形容。为什么是static?因为只要是static描述的,都会在这个类的对象第一次被创建时,在内存中创立,初始化,接下来再创建对象时,就不会有这部分内容的动作了,所以相比于非static的,它的动作更少,所以叫静态。
用static修饰的,术语叫类XX,因为它是属于类的特性,没用static的,叫实例XX,它们是属于实例的特性。举个例子,比如Person类中有static变量eyecount,非static变量weight。那么我们要用eyecount的时候可以直接Person.eyecount,但也可以xiaowang.eyecount(虽然这种用法不科学,但就是可以);当我们要用weight的时候,可以用xiaowang.weight,此时用Person.weight是坚决不可以的!
总结一下就是:动可用静,动动静静,静不能动。
封装(Encapsulation,面向对象三大特征其一):
我们为什么想要用封装?首先封装可以将问题模块化,使解决问题变得简单;其次封装可以实现对一些关键信息的保护,我只提供你这么多操作,但是想直接摸到那些信息?NO WAY。所以一般封装会隐藏对象Feild、实现细节,而会暴露一些访问Feild的方法。
访问控制符:
private(当前类访问权限) > default(包访问权限) > protected(子类访问权限) > public(公共访问权限)
使用原则:
1.绝大数Feild使用private,少数用static修饰、类似全局变量的Feild用public修饰,工具方法用private。
2.一个类主要作为父类时,多用protected修饰。
3.希望暴露的用public
包(package):
这得好好总结总结。类似于c语言中的那种include一个库函数的功能,但是强大的是,我们可以在原来的库的基础上,做一些自己需要的改动,同时不影响原来的库。包就是包含了一组功能相关的类,组成逻辑上的类库单元。涉及到包的有两个指令。先讲import,这个很好理解,跟include功能类似,相当于扩充了CLASSPATH。
还有一个是package指令,这个非常容易错。当你自己想设计一个库的时候,package就有用了。package后面加包名,其实这个包名非常像一个目录,不过目录的‘/‘变成了‘.‘而已。package后面跟的这个包名,就是当前的类在包中所处的位置。举个例子,我在当前目录java下新建了一个包,叫cer,下面有一个类叫hello.class,那么在hello.class里第一句就是package
cer;算是表明身份,亮出自己的站队。
到了这里还没有结束,接下来涉及到编译。我们编译的时候,怎么编呢?如果我们hello.java文件,是在java目录中创建的,那么我们如果还是用原来的javac hello.java指令的话,结果就是产生的hello.class也在java下,这就不对了。因为我们期望它在cer下。所以这时候应该使用javac -d . hello.java 指令,这样的话,编译器会根据源文件里第一句话package
cer去创建cer目录,然后把hello.class放到cer下。
你以为这样就完了?呵呵,还没有!运行时,你说怎么运行?按理说进到cer下java hello应该可以执行才对,但是人说类,不可以。你只能在当前目录下,也就是java下,输入java cer.hello。当一个类在包中的时候,编译时一定要给出它在包中的相对目录(没错,我想到的就是这个词,相对目录,准确的说应该是包中的相对位置),而且运行时应该处于包所在目录下才行哦。这样就可以根据包的位置,再加上相对位置,准确定位那个类啦。真是规矩一大堆,但是到你编写一个复杂项目时,这肯定能帮你理清文件位置关系。
总结一下就是Java的包机制需要有两方面的保证:1.源文件里使用package语句指定包名;2.class文件必须放在对应的路径下。
继承(Extends,面向对象三大特征其二):
很好理解,class A extends B,就代表着A类继承了B类,A是B的子类,B是A的父类。继承以后,A将拥有所有B的非private的Field和方法。
多态(Polymorphism,面向对象三大特征其三):
这也不难理解,想像你有一个好兄弟,你对他非常了解,也就是他的Feild和方法。当你去看他儿子的时候,你作为他父亲的同辈,必定会以看他父亲的眼光去看他,这就是多态。用程序表示就是:Base pc = new Sub();看到没,就是拿父类引用变量去引用子类对象。这还有种叫法叫向上转型(upcasting)。这在什么时候用呢?举个例子,父类Person,子类xiaowang,xiaoli。假设父类和子类有共同的方法都叫run(),但是子方法有所改变,小王的run,非常快,小李的run非常慢,假如我们的程序不知道要选小王还是小李,那么就应该这样写ChooseOneToRun(Person
p){p.run();}。这样的话不管小王还是小李,都能顺利地run拉!
toString()和valueOf():
这两个是在字符串转换中非常有用的两个方法。toString()方法就是把各种各样类型的数据转换成字符串,这其中还包括引用对象的类型哦,不过在这种情况下,toString()最好自己重写一遍。valueOf()方法可看作是toSrting()方法的逆方法,它把用字符串表示的数据转换成其他类型。比如有个String叫s,内容是“123”,那就可以调用valueOf(),把它转换成int的123。反过来,int的123可以用toString()转换成字符串的“123”。这两个方法很常用。记得上回总结System.out.println()的时候,就说到这个方法在用的时候,先会将变量都转换成字符串的格式,其实就是隐式地调用了toString()方法。
final关键字:
有些量和方法,我们希望定义了一次,它就不能再被定义了,这个时候,我们需要final。作用有点像c语言中的宏定义。需要注意的是final修饰的引用类型的变量,如果我们想让一个对象在定义完后其内容都不变,则需要加上一些其他操作,在此不赘述。final修饰的类不可以有子类,这真是一个断子绝孙的关键字阿!
抽象类abstract关键字:
抽象类中必有抽象方法,抽象方法可以没有方法体。那没有方法体的方法体,要它何用?让子类继承,然后再根据子类的特性,补充所需的方法即可。其实抽象类体现的是一种模板模式的设计,它规定了子类大概要写什么却让子类自己补充完整。这多像咱考四六级时背的作文模板阿!给个大框,抠几个洞,自我发挥。有一点要注意,抽象类不能创建自己的实例。
接口(interface):
接口和一个abstract的类有点像,但它更绝,更抽象,它只能包含抽象方法。接口也不能有实例,但接口可以多重继承,一个接口可以有多个直接父接口。接口体现的是一种规范,对于调用者而言,接口规定类调用者可以调用哪些服务,以及如何调用这些服务;对于实现者来说,接口规定了实现者必须向外提供那些服务。接口里只含有Field和方法,所有的常量、方法都是public修饰,而且Field默认隐式地加上public
static final,所以有的时候你看一个接口,会有一种看到c语言的错觉。
匿名内部类:
因为感觉这个容易犯迷糊,所以多说一嘴。创建匿名内部类时会立即创建一个该类的实例,这就好像是一次性的一个类。你想,以前你定义一个类,它可以实例化出多个实例,但匿名类却是类和实例绑定在了一起,实行一夫一妻制。格式
new 父类构造器(实参列表)|实现接口()
{//匿名类内部类的类体部分}
枚举类(enum):
有点像c语言中的枚举类型,它限定了这个类实体化以后的对象,必须是它指定的其中一个。好比四季,你不能再举出第五个季节,又好比性别,只有男女。
好的今天内容就到这里。可能有些朋友看了我的文章会觉得:天呐,这是什么东东,考试复习提纲吗?NO,我写这样的总结笔记,更多是为了理清思路,温故知新。可能读起来体验不是那么好,但是过一遍也算是复习吧!欢迎评论指正!