Java三大特性(封装、继承、重写实例讲解)

时间:2018-09-13
本文章向大家介绍Java三大特性(封装、继承、重写实例讲解),需要的朋友可以参考一下

Java 三大特性,算是Java独特的表现,提到Java 的三大特性, 我们都会想到封装, 继承和多态 这是我们Java 最重要的特性。

封装(Encapsulation) : 

封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

好处:
• 将变化隔离。
• 便于使用。
• 提高重用性。
• 提高安全性。
 封装原则:
• 将不需要对外提供的内容都隐藏起来。
• 把属性都隐藏,提供公共方法对其访问 。

private关键字:

• 是一个权限修饰符。

• 用于修饰成员(成员变量和成员函数)

• 被私有化的成员只在本类中有效。

常用之一:

将成员变量私有化,对外提供对应的set , get方法对其进行访问。提高对数据访问的安全性。

举个栗子:  

我们常说的失血模型

 1 public class Demo {
 2     
 3         private String name;
 4         private String sex ; 
 5         private int age;
 6         public String getName() {
 7             return name;
 8         }
 9         public void setName(String name) {
10             this.name = name;
11         }
12         public String getSex() {
13             return sex;
14         }
15         public void setSex(String sex) {
16             this.sex = sex;
17         }
18         public int getAge() {
19             return age;
20         }
21         public void setAge(int age) {
22             this.age = age;
23         }
24         
25         
26 }

继承(inheritance):

继承是面向对象最显著的一个特性。 继承是从已有的类中派生出新的类, 新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
在JAVA中, 被继承的类叫父类(parent class)或超类(superclass), 继承父类的类叫子类(subclass)或派生类(derivedclass)。 因此, 子类是父类的一个专门用途的版本, 它继承了父类中定义的所有实例变量和方法, 并且增加了独特的元素 。

继承的结构:

继承的使用 :

关键字:extends。

 1 使用继承
 2 – 编写父类
 3 – 编写子类, 继承父类
 4 class Animal {
 5 //公共的属性和方法
 6 } 
 7 class Chicken extends Animal{
 8 //子类特有的属性和方法
 9 }
10  class Duck extends Animal {
11 }

基本语法:

1 基本语法
2 
3 class Chicken extends Animal{ }
4 
5 上述代码表示Chicken类继承Animal类,使用extends关键词将Animal类(父类/超类)和Chicken类(子类)连接接起来;
6 在继承关系下,Chicken类将拥有Animal类所有的非私有的方法和属性,Chicken类还可以拥有自己独有的方法和属性;
7 声明Animal类,实例化Chicken类时, Chicken类会自动向上转型为Animal类;

 举个栗子:

 1 //创建动物类
 2 
 3 public class Animal {
 4 private String type;
 5 private String skin;
 6 private int legCount;
 7 public void eat(){
 8 System.out.println("动物正在吃东西");
 9 }
10 public void breath(){
11 System.out.println("动物正在呼吸");
12 }
13 public String getType() {
14 return type;
15 }
16 public void setType(String type) {
17 this.type = type;
18 }
19 public String getSkin() {
20 return skin;
21 }
22 public void setSkin(String skin) {
23 this.skin = skin;
24 }
25 public int getLegCount() {
26 return legCount;
27 }
28 public void setLegCount(int legCount) {
29 this.legCount = legCount;
30 }
31 }
32 
33 //鸡类
34 public class Chicken extends Animal {
35 public void eat(){
36 System.out.println(“鸡正在吃东西”);
37 } 
38 public void run(){
39 System.out.println(“鸡在跑");
40 }
41 }
42 
43 //鸭类
44 public class Duck extends Animal {
45 public void eat(){
46 System.out.println(“鸭正在吃东西”);
47 }
48  public void run(){
49 System.out.println(“鸭在跑");
50 }
51 }
52 
53 //测试类
54 
55 public class Test {
56 public static void main(String[] args){
57 Chicken chicken=new Chicken ();
58 chicken.eat();
59 chicken.setType(“鸡”);
60 chicken.setSkin(“金色");
61 chicken.setLegCount(2);
62 System.out.println("动物品种是: "+chicken.getType()+", 肤色是: "+chicken.getSkin()+", 腿数"+t.getLegCount());
63 chicken.run();
64 Duck duck =new Duck ();
65 duck.eat();
66 duck.fight();
67 }
68 }

继承执行的顺序:

java中, new一个类的对象, 类里面的静态代码块、 非静态代码块、无参构造方法、 有参构造方法、 类的一般方法等部分, 它们的执行顺序相对比较简单, 例如: 

 1 public class FatherTest{
 2 private String name;
 3 public FatherTest(){
 4 System.out.println(“--父类的无参数构造方法--”);
 5 }
 6 public FatherTest(String name){
 7 System.out.println(“--父类的有参数构造方法--”+this.name);
 8 }
 9 static{
10 System.out.println(“--父类的静态代码块--”);
11 }
12 {
13 System.out.println(“--父类的非静态代码块--”);
14 }
15 public void speak(){
16 System.out.println(“--父类的方法--”);
17 }
18 }
19 
20 public static void main(String[] args){
21 System.out.println(“--父类主程序--”);
22 FatherTest father = new FatherTest(“父亲的名字”);
23 father.speak();
24 }
25 
26 执行结果为:
27 --父类的静态代码块--
28 --父类主程序--
29 --父类的非静态代码块--
30 --父类的有参构造函数--父亲的名字
31 --父类的方法--
32 
33 执行顺序总结:
34   静态代码块—>主程序—>非静态代码块—>构造函数—>一般方法

加入子类继承后的执行顺序, 例如 :

 1 public class SonTest extends FatherTest{
 2 private String name;
 3 static{ 
 4 System.out.println("--子类的静态代码块--"); }
 5 {
 6  System.out.println("--子类的非静态代码块--");
 7  }
 8 public SonTest(){ 
 9 System.out.println("--子类的无参构造方法--");
10  }
11 public SonTest(String name){ 
12 System.out.println("--子类的有参构造方法--"+name);
13  }
14 @Override
15 public void speak() { System.out.println("--子类重写了父类的方法--"); }
16 }
17 
18 
19 public static void main(String[] args) {
20 System.out.println("--子类主程序--");
21 FatherTest father=new FatherTest("父亲的名字");
22 father.speak();
23 SonTest son=new SonTest("儿子的名字");
24 son.speak();
25 }
26 
27 执行结果为:
28 --父类的静态代码块--
29 --子类的静态代码块--
30 --子类主程序--
31 --父类的非静态代码块--
32 --父类的有参构造函数--父亲的名字
33 --父类的方法--
34 --父类的非静态代码块--
35 --父类的无参构造函数--
36 --子类的非静态代码块--
37 --子类的有参构造方法--儿子的名字
38 --子类重写了父类的方法--

方法的重写:

方法重写是在继承关系下, 子类拥有与父类方法名、 参数(个数、顺序、 类型)、 返回值类型完全相同, 访问修饰符只能扩大或相等, 不可缩小, 但实现过程与父类不同的方法。 方法重写也是多态的一种变现形式。 

重写必须满足以下几个条件:
在子类中可以根据需要对从基类中继承来的方法进行重写;
重写的方法和被重写的方法必须具有相同方法名称、 参数列表和返回类型; 
重写方法不能使用比被重写的方法更严格的访问权限 ;

举个栗子:

//鸡类
class Chicken extends Animal {
public void eat(){
System.out.println(“鸡正在吃东西”);//对父类Animal中的eat方法进
行重写
}
 public void run(){
System.out.println(“鸡在跑");//可以添加新的方法
}
}

Super关键字:

super关键字是一个特殊的变量, 它提供了对父类的方法。 可以用super主动调用父类的构造方法、 访问父类中的成员。 

 super调用父类的构造方法:

public class Duck extends Animal {
public Duck(String name){
super(name);//主动调用父类的构造方法
}
}

super访问父类的成员:

在子类方法中使用super访问父类中隐藏的成员, 访问形式是:
super.变量;
super.方法名(参数);

 1 public class Duck extends Animal {
 2 @Override
 3 public void eat() {
 4 System.out.println();
 5 }
 6 public void quack(){
 7 System.out.println(super.name);//使用super调用父类的属性
 8 eat();
 9 super.eat();//使用super调用父类的eat()方法
10 }
11 public static void main(String[] args) {
12 new Duck().quack();//创建Duck类对象并调用quack方法
13 }
14 }

final 关键字:

“final”关键字用来修饰类、 方法和变量, 其含义“不可改变的、 最终的”。

1 修饰类 声明为final的类不能派生子类,即此类不能被继承;
2 public final class Person{ }
3 修饰变量 表示它为一个常量,变量一旦初始化,将不能改变;
4 final int COUNT = 5;
5 修饰方法 表示向编译器表明子类不能重写此方法;
6 public final void eat(){ }

多态(polymorphism) 

在面向对象语言中, 多态性是指一个方法可以有多种实现版本,即“一种定义, 多种实现”。 利用多态可以设计和实现可扩展的系统, 只要新类也在继承层次中。 新的类对程序的通用部分只需进行很少的修改, 或不做修改。 类的多态性表现为方法的多态性,方法的多态性主要有方法的重载和方法的覆盖。

重载:

 方法重载(overload)是指在同一个类中的多个方法可以同名但参数列表必须不同。 重载表现为同一个类中方法的多态性。

class Chicken {
public void eat(){
System.out.println(“鸡正在吃东西”);
}
public void eat(String food){
System.out.println(“鸡在吃"+food);//重载eat方法
}
} 

 方法重写(override)是指子类冲定义了父类中同名的方法。 重写表现为父子与子类之间方法的多态性。

   //鸡类
class Chicken extends Animal {
public void eat(){
System.out.println(“鸡正在吃东西”);//对父类Animal中的eat方法进
行重写
}
}

对象类型转换: 

基本类型的数据可以转换类型, 当转换类型较高时可以自动转换, 当转换类型较低时需要强制转换。 对象类型也允许转换, 这个转换只限于java类层次结构图上的一根枝干上, 即父类和子类之间。 枝干上离Object较近的为上, 相反较远的为下, 由此对象的类型转换分为“向上转型”和“向下转型”两种。

 1   public class Duck extends Animal {
 2 @Override
 3 public void eat() {
 4 System.out.println();
 5 }
 6 public void quack(){
 7 System.out.println("嘎嘎嘎");
 8 }
 9 public static void main(String[] args) {
10 Animal a1 = new Animal();//实例化过程
11 Animal a2 = new Duck();//向上转型
12 a1.eat();
13 a2.eat();
14 //a2.quack();//去除注释会怎样?
15 }
16 }

向下转型:只能针对指向子类对象的基类对象引用进行 。

 1 public class Duck extends Animal {
 2 @Override
 3 public void eat() {
 4 System.out.println();
 5 }
 6 public void quack(){
 7 System.out.println("嘎嘎嘎");
 8 }
 9 public static void main(String[] args) {
10 Animal a = new Duck();//向上转型
11 Duck b = (Duck) a;//向下转型
12 a.eat();
13 b.eat();
14 b.quack();
15 }
16 }

Instanceof 关键字 :

instanceof关键字是用来判断其左边对象是否为其右边的实例, 返回boolean类型的数据 .

boolean result = Object instanceof class

同时, 也可以用来判断继承中的子类的实例是否为父类的实现。

.....
public static void main(String[] args) {
Animal a = new Duck();//向上转型
if(a instanceof Duck){
((Duck) a).quack();
}
}
.....