前情回顾:今天回到Java基础,前两篇Java基础讲到JDK、JRE、JVM和语法基础等东西,认识到基础的重要性后,现在要更加沉下心来好好努力才行。
今天遇到点事,心情不是很愉快。如果换做以前,我可能会郁闷一整天,就光想着那些让我不开心的人是多么地可恶。而现在,可能是年岁渐长的缘故,已经不会那么肆意地拿别人的错误来惩罚自己了。更何况,我还有我的事情要做。没错,今天的博客还没写呢,哪来这么多时间去哀怨愤怒呢?
昨天在心理FM听到一篇文章,很喜欢里面的这么一段话:“苦难是世界上最没有意义的事情,没有人会想要发生在自己身上。但是若苦难来临,我们不能消沉、不能堕落、不能发了疯,而是必须要去面对,像钢铁一样活下去。”
———————————————————————————————闲聊结束—————————————————————————————————
第五章:继承与多态
在面向对象中,继承(Inherit)指的是子类继承父类,避免重复的行为定义。
可是,经常有人会滥用继承,导致程序维护上出现问题。所以说,如何正确判断使用继承的时机,以及使用继承之后怎么样灵活应用多态,是学习继承的重点。
第一节:继承
子类继承父类的关键字是extends。假设有父类Animal,继承父类Animal的子类Dog。那么子类与父类之间会有is-a的关系,翻译成中文就是“是一种”的关系。举例,子类Dog继承了父类Animal,就有了父类的所有特征,那么Dog就是一种Animal。再假设子类Cat也继承了父类Animal,那么下面的语句能通过编译么?
1 Dog dog=new Animal();2 Cat cat=new Animal();
答案当然是不能,为什么呢?理由我们等会再说,再看下面两条语句:
1 Animal animal1=new Cat();2 Animal animal2=new Dog();
这两条语句却可以通过编译,为什么呢?是因为,我们可以把语句这么看,“=”换做“is-a”而且倒着看,那么Dog dog=new Animal()就可以看做“Animal is a dog”,翻译成中文就是动物是一种狗。这明显是错误的,因为动物包括很多种,并不一定是狗。而Animal animal1=new Dog()就可以看做“Dog is a animal”(狗是一种动物),这就对了。
第二节:方法重写与方法重载
在继承父类之后,如果父类的某个方法不符合需求,那么我们定义与父类中相同的方法部署,这就叫做方法重写(Override)。如果想使用父类方法,可以使用super关键字,例如:super.method();
在笔试面试题中,常常会问到:方法重写跟方法重载的区别是什么?下面简单解答一下:
方法重写是子类的方法覆盖父类的方法,要求方法名和参数都相同。而方法重载(Overroad)是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同(参数不相同,可以是个数不相同,也可以是类型不相同),方法体也不相同,最常见的重载的例子就是类的构造函数。
第三节:抽象方法与抽象类
如果某个方法代码块里面没有任何程序代码操作,我们可以使用abstract标示该方法为抽象方法(Abstract method),该方法不用撰写{}代码块,直接用“;”结束即可。
1 package cc.openhome;2 3 public abstract class Role {4 ...5 public abstract void fight();6 }
Java中规定内含抽象方法的类,一定要在class前标示abstract,标示这是一个定义不完整的抽象类(Abstract class)。如果尝试用抽象类创建实例,就会发生编译错误。
子类如果继承抽象类,那么对于抽象方法有两种方法,一种做法是继续标示该方法为abstract(该子类因此也是个抽象类,必须在class前标示abstract);另外一种做法就是实现操作方法。如果不做这些,也是会发生编译错误的。
第四节:权限关键字与范围
在Java中三个权限关键字分别是public、protected与private。其实,如果没有用这三个关键字修饰的话,也会有默认的权限限制,我们暂且称之为default。
这些关键字都可以用来修饰类成员对象以及类方法,而class则只能用public或default修饰。
第五节:类加载过程与final关键字
在创建类的实例时,类中各成员的执行顺序是什么样的呢?(在笔试中就遇到这个题,我华丽丽地做错了)
(1)父类静态成员和静态初始化块,按在代码中出现的顺序依次执行;
(2)子类静态成员和静态初始化块,按在代码中出现的顺序依次执行;
(3)父类实例成员和实例初始化块,按在代码中出现的顺序依次执行;
(4)执行父类构造方法
(5)子类实例成员和实例初始化块,按在代码中出现的顺序依次执行;
(6)执行子类构造方法
那么,final关键字是干嘛用的?final,作为英语中形容词的时候,有最后的,最终的;决定性的;不可更改的意思。那么在java中,如果在给变量赋值之后就不再改变变量值了,可以在声明变量时加上final关键字。如果在后面的代码中有修改final变量的操作,就会出现编译错误。如果对象数据成员被声明final,但没有明确使用=指定值,那表示延迟对象成员值的指定,在构造函数执行流程中,一定要有对该数据成员指定值的操作,不然,还是会出现编译错误。
如果是class用final修饰,那么就表示这个类不能被继承,就例如我们常常用到的String类,就是用final关键字修饰的,不能被继承。如果对String类进行继承,就会发生编译错误。如果方法用final修饰,那么就表示这个方法不能被重写,例如java.lang.Object里就有好几个final方法,例如Object.notify().
第六节:说说Object类
在Java中,规定一个子类只能继承一个父类,如果定义类的时候没有使用extends关键字指定继承任何类,那一定是直接继承java.lang.Object。因此在Java中,任何类追溯到最上层父类,一定就是java.lang.Object,也就是Java中所有对象,一定“是一种”Object。所以像下面这两行语句,肯定是可以通过编译的:
1 Object o1="Justin";2 Object o2=new Dog();
java.lang.Object是所有类的顶层父类,这代表了Object上定义的方法,所有对象都继承下来了。
上面是JavaAPI说明文档的截图,建议大家尽量多去看看API,有时候还是挺涨姿势的。只要不是被定义为final方法的,都可以进行方法重写。被重写最多的,大概就是equals()这个方法了。重写equals()时一般都会跟hashCode()扯上关系,所以并非那么简单。值得注意的是,2007年的一篇研究文献Declarative Object Identity Using Relation Types中指出,在考察大量Java程序代码之后,作者发现大部分的equals()方法都存在着错误。
相关内容,将会在之后的内容中说明,敬请期待。
第七节:简单提一提GC
什么是GC呢?GC,Garbage Collection,是垃圾回收的意思。
GC功能会自动监测对象是否超过作用域,从而达到回收内存的目的。值得注意的是,Java语言没有提供释放已分配内存的显示操作。(当程序有一定的等待时间,程序员可以自动执行System.gc(),通知GC运行,但是Java语言规范并不会保证GC一定会执行。)
分配对象用new,释放对象用null;通常GC都会采用有向图的方式记录并管理堆中的所有对象。
针对GC,在Java编程时,有以下两点建议,以供参考:
1.尽早释放无用对象的引用,尤其注意复杂对象,例如:数组、队列
2.尽量少用finalize函数。finalize是Java提供给程序员用来释放对象或资源的函数,但会加大GC的工作量
今天的内容就到这里,话说我后天二面,童鞋们默默给我加油吧。
——————————————————————————————第十七天———————————————————————————————————
今天写的状态还不错,要继续坚持下去才好。
1.今天聊到面对痛苦和烦恼,我一直对自己说,可以恐惧,可以害怕,但是不能退缩,不能认输,因为这样,那就真的输了。
2.继续介绍心理FM,那篇文章叫做《苦难有什么价值》,地址是http://fm.xinli001.com/816/
3.程序员,在关注技术和行业的同时,也可以花点时间在别的方面,舒缓一下心情,换换脑子也好。