面试中常常会问及Java细节相关的问题,而由于往往在平时中不会过多的涉及,所以不能得心应手。而通过阅读课本和网上资料,会有一定的帮助,但纸上得来终觉浅,绝知此事须躬行。以博客的形式梳理思路,通过一行行代码,深入理解Java细节,从而对于Java高级特性进行全面掌握。
Java三大特性
封装
- 封装三大好处
- 良好的封装减少耦合
- 类内部的结构可以自由修改(无须修改客户代码)
- 可以对成员进行精确控制(年龄范围,性别控制等)
- 隐藏信息,实现细节(对象的属性私有化)
继承
通过继承(is-a)实现代码的复用。
- 继承特点
- 子类拥有父类非private的属性和方法
- 子类可以拥有自己的属性和方法
- 子类可以用自己的方式实现父类的方法(重写)
- 构造器
- 只能被调用,不能被继承,super()调用父类的构造器。
- 子类会默认调用父类的构造器。
- 如果没有默认的父类构造器,子类必须显示调用指定父类的构造器,而且必须在子类构造器中的第一行代码实现调用。
public class Person {
protected String name;
protected int age;
protected String sex;
Person(String name){
System.out.println("Person Constrctor-----" + name);
}
}
public class Husband extends Person{
private Wife wife;
Husband(){
super("chenssy");
System.out.println("Husband Constructor...");
}
public static void main(String[] args) {
Husband husband = new Husband();
}
}
Output:
Person Constrctor-----chenssy
Husband Constructor...
- protected关键字
- 尽可能隐藏,但是允许子类的成员访问。
- 指明就类用户而言,他是private,但是对于任何继承与此类的子类而言或者其他任何位于同一个包的类而言,他却是可以访问的。
public class Person {
private String name;
private int age;
private String sex;
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
public String toString(){
return "this name is " + name;
}
/** 省略其他setter、getter方法 **/
}
public class Husband extends Person{
private Wife wife;
public String toString(){
setName("chenssy"); //调用父类的setName();
return super.toString(); //调用父类的toString()方法
}
public static void main(String[] args) {
Husband husband = new Husband();
System.out.println(husband.toString());
}
}
Output:
this name is chenssy
- 向上转型
- 专用类型向较通用类型转换,所以总是安全的。
- 可能带来属性和方法的丢失。
public class Person {
public void display(){
System.out.println("Play Person...");
}
static void display(Person person){
person.display();
}
}
public class Husband extends Person{
public static void main(String[] args) {
Husband husband = new Husband();
Person.display(husband); //向上转型
}
}
多态
指向子类的父类引用由于向上转型,只能访问父类中拥有的方法和属性,会丢失子类中存在,而父类中不存真的方法。若子类重写了父类的某些方法,在调用方法的时候,必定会使用子类中定义的方法。(动态连接,动态调用。
public class Wine {
public void fun1(){
System.out.println("Wine 的Fun.....");
fun2();
}
public void fun2(){
System.out.println("Wine 的Fun2...");
}
}
public class JNC extends Wine{
/**
* @desc 子类重载父类方法
* 父类中不存在该方法,向上转型后,父类是不能引用该方法的
* @param a
* @return void
*/
public void fun1(String a){
System.out.println("JNC 的 Fun1...");
fun2();
}
/**
* 子类重写父类方法
* 指向子类的父类引用调用fun2时,必定是调用该方法
*/
public void fun2(){
System.out.println("JNC 的Fun2...");
}
}
public class Test {
public static void main(String[] args) {
Wine a = new JNC();
a.fun1();
}
}
-------------------------------------------------
Output:
Wine 的Fun.....
JNC 的Fun2...
- 多态的实现
- 条件(继承、重写、 向上转型)
- 实现形式(继承、接口)当子类重写父类的方法被调用时,只有对象继承链中的最末端的方法才会被调用
- 经典案例分析
public class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
}
}
public class B extends A{
public String show(B obj){
return ("B and B&#