欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java三大特性(封装,继承,多态)

程序员文章站 2022-03-26 21:46:22
Java中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的. 一.封装 概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类” ......

Java中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的.

一.封装

概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“类”,其中数据和函数都是类的成员。在电子方面,封装是指把硅片上的电路管脚,用导线接引到外部接头处,以便与其它器件连接。(来自百度)

在将成员属性封装之后,我们应该提供相应的get/set方法进行访问此成员属性.

封装的好处是:属性进行了隐藏,不再是暴露在外的数据,使数据更加的安全可靠.

 1 class A{
 2     private int a;//此变量进行了封装
 3     //提供给外部访问的接口,实现了只读和只写
 4     public int getA(){
 5         return a;
 6     }
 7     public void setA(int a){
 8         this.a=a;
 9     }
10 }

提到封装就必须要提到private关键字,如上代码,private是一个权限修饰符,它可以将成员方法和成员属性私有化,使其只有类内部能够访问到.

权限修饰符有4种,分别是public->protected->default->private 其中private权限最严格

public:可以在全工程访问到      protected:只有这个类的子类可以访问     defaule:为默认,无须写出,类所在包下可以访问     private:仅仅只有本省类可以访问

 

提到了封装就不得不提到this关键字

概念:this关键字指这个当前对象的引用

this关键字有三种用法:

  1.this.成员方法,这种方法用于给成员变量的赋值.

 1 class A{
 2     private int a;//此变量进行了封装
 3     //提供给外部访问的接口,实现了只读和只写
 4     public int getA(){
 5         return a;
 6     }
 7     public void setA(int a){
 8         this.a=a;
 9     }
10 }

  因为就近原则,所以直接a=a;实际上并没有对成员属性进行赋值,所以需要使用this关键字对其进行访问.

  2.调用构造方法,如:可以在空参构造方法中调用有参构造方法

 1 class A{
 2     private int a;//此变量进行了封装
 3     //提供给外部访问的接口,实现了只读和只写
 4     public int getA(){
 5         return a;
 6     }
 7     public void setA(int a){
 8         this.a=a;
 9     }
10     //空参构造
11     public A(){
12         this(1);
13     }
14     //全参构造
15     public A(int a){
16         this.a=a;
17     }
18 }

  这个例子使用this在空参构造中调用了全参构造

  使用this调用构造方法时需要注意:

    1.this()必须在构造方法中的第一行,且只能够使用一次

    2.this()不能够互相调用,因为会陷入死循环,如下:

 1 class A{
 2     private int a;//此变量进行了封装
 3     //提供给外部访问的接口,实现了只读和只写
 4     public int getA(){
 5         return a;
 6     }
 7     public void setA(int a){
 8        this.a=a;
 9     }
10     //空参构造
11     public A(){
12         this(1);
13         //this();错误
14     }
15     //全参构造
16     public A(int a){
17         //this();错误
18         this.a=a;
19     }
20 }

  3.this可以当作返回值使用,this是当前对象的引用,所以返回的同样是一个A类型,可以使用一个新的A类型对象b进行接受,b会继承所有a的属性值,使用方法如下:

class A{
    private int a;//此变量进行了封装
    //提供给外部访问的接口,实现了只读和只写
    public int getA(){
        return a;
    }
    public void setA(int a){
        this.a=a;
    }
    //使用this当作返回值
    A b(){
        return this;
    }
    //空参构造
    public A(){
        this(1);
    }
    //全参构造
    public A(int a){
        this.a=a;
    }
}

 

二.继承

 概念:继承即从已有的类中派生一个新的类,已有的类成为父类(基类,超类),而派生的类成为子类(派生类).若类B继承了类A,则我们把类A称为类B的子类,反之同理,子类可以拥有自己本身的特有方法以及特有属性,而父类则必须是子类的共性抽取.如动物都有颜色,年龄,其颜色和年龄就是其共性

1 class A{
2     int a;
3     void a(){}
4 }
5 class B extends A{
6     //子类特有方法
7     void b(){
8     }
9 }

 

1. 继承需要注意的点

  (1)继承是类在继承,而不是对象在继承

  (2)子类无条件继承父类的所有成员属性及成员方法

  (3)若方法出现重写,属性出现重复,则优先使用子类的方法和属性(就近原则).

  (4)继承不继承父类的构造方法

2.java中继承的特点

  (1).java不支持多继承,但是可以通过接口实现多继承        多继承,即子类继承自多个父类

  (2).java支持多重继承        多重继承,即子类继承父类,父类继承他的父类,即子类相当于其孙子辈

class A{
    int a;
    public A(){
        //super();这里有一个默认的super()方法
    }
    public A(int a){
        //super();这里有一个默认的super()方法
    }
    void a(){}
}
class B extends A{
    //子类的特有属性
    int b;
    //子类特有方法
    void b(){
        //调用父类的成员属性
        System.out.println(super.a);
        //调用父类的成员方法
        super.a();
    }
    public B(){
    //调用父类的有参构造 super(1); } }

 

提到继承就必须提到super关键字,super关键字指父类的引用,super关键字最重要的是每个类的构造方法都有其默认的一个super()方法,我们知道所有的类都是继承自Object类,而super()这个方法其实是调用到Object处进行空间的申请.

super关键字的使用

  1.访问父类成员方法和成员属性     super.成员方法()       super.成员属性

  2.访问父类的构造方法        super(参数)

 

 1 abstract class Animal{
 2     private String color;
 3     private int numOfLegs;
 4     abstract void eat();
 5     public String getColor() {
 6         return color;
 7     }
 8     public void setColor(String color) {
 9         this.color = color;
10     }
11     public int getNumOfLegs() {
12         return numOfLegs;
13     }
14     public void setNumOfLegs(int numOfLegs) {
15         this.numOfLegs = numOfLegs;
16     }
17     public Animal(String color, int numOfLegs) {
18         super();
19         this.color = color;
20         this.numOfLegs = numOfLegs;
21     }
22     public Animal() {
23         super();
24     }
25     
26 }
27 class Dog extends Animal{
28     Dog(){
29         super();
30     }
31     Dog(String color,int numOfLegs){
32         super(color,numOfLegs);
33     }
34     @Override
35     void eat(){
36         System.out.println(super.getNumOfLegs()+"条腿"+super.getColor()+"的狗在啃骨头");
37     }
38     void lookHome(){
39         System.out.println(super.getNumOfLegs()+"条腿"+super.getColor()+"的狗在看家");
40     }
41 }
42 class Porrot extends Animal{
43     Porrot(){
44         super();
45     }
46     Porrot(String color,int numOfLegs){
47         super(color,numOfLegs);
48     }
49     @Override
50     void eat(){
51         System.out.println(super.getNumOfLegs()+"条腿的"+super.getColor()+"鹦鹉在吃小米");
52     }
53     void say(){
54         System.out.println(super.getNumOfLegs()+"条腿的"+super.getColor()+"鹦鹉在说你好,丑八怪");
55     }
56 }

提到继承当然也不能不提到抽象类,定义一个抽象类使用是这样的:public abstract class Animal(){}

当你想要创建一个动物类时,你知道动物都会吃,但是你不知道动物的子类吃是如何具体实现的,如:猫吃鱼,但是狗吃的是骨头同样的子类,但是其方法的实现却是不同的,这个时候就需要使用抽象类了.

抽象类的注意点:

  1.抽象类必须在类中使用abstract关键字进行修饰,

  2.抽象类中可以没有抽象方法,

  3.抽象类不能够实例化,如果想要实例化的话则需要子类将其所有的抽象方法重写

 

 1 interface A{
 2     int b=0;//默认有public static final;
 3     void a(){}//默认有public abstract;
 4 }
 5 interface B{
 6 }
 7 class Father{
 8 }
 9 class Son extends Father implements A,B{
10     //方法的实现
11     public void a(){
12     }
13 }

 

提到抽象类就一定要提到接口

接口:接口其实相当于一个规范,当你定义一个接口时,实现接口的类必须实现接口中的所有的方法.举个现实中的例子,比如我们的手机充电借口,基本很少发生改变,因为他已经是规定死了的,使用接口等于制定一个规范,等于是所有的实现此接口的类都必须实现此规范,这样就可以用接口来实现不同类的比较等操作.

接口的注意点:

  1.接口中的成员属性必须都是public static final的,不修饰会自动加上,接口中的成员方法必须都是public static修饰的,且不可以使用其他的权限修饰符

  2.接口不可以被实例化,必须使用子类 explements 接口,然后实现接口中的方法.

  3.一个类可以实现多个接口,可以在实现抽象类的同时实现多个接口或单个接口

 

三.多态

概念:同一个行为,对于传入不同的对象,实现不同的动作              多态需要记住的一个概念:父类引用指向子类对象

多态的好处:提高了代码的可复用性.

多态的坏处:无法使用子类所特有的方法.因为编译时看的是右边.

多态的实现必须有三要素  1.继承(实现)  2.重写  3.向上转型(缺一不可!!!)

 1 public class Test{
 2     public static void main(String[] args){
 3         show(new Dog());
 4         show(new Cat());
 5     }
 6     public static void show(Animal a){
 7         a.eat();
 8     }
 9 }
10 abstract class Animal{
11     abstract void eat(){
12     }
13 }
14 class Dog extends Animal{
15     public void eat(){
16         System.out.println("在吃骨头");
17     }
18 }
19 class Cat extends Animal{
20     public void eat(){
21         System.out.println("在吃鱼");
22     }
23 }

多态基于继承的实现如上.

public class Test01{
    public static void main(String[] args){
        show(new Dog());
        show(new Cat());
    }
    public static void show(Animal a){
        a.eat();
    }
}
interface Animal{
    abstract void eat();
}
class Dog implements Animal{
    public void eat(){
        System.out.println("在吃骨头");
    }
}
class Cat implements Animal{
    public void eat(){
        System.out.println("在吃鱼");
    }
}

接口的实现如上

 

提到多态就需要提到一个例子:

public class Test01{
    public static void main(String[] args){
        A a1=new A();
        A a2=new B();
        B b=new B();
        C c=new C();
        D d=new D();
        
        a1.show(b);// a and a
        a1.show(c);//a and a
        a1.show(d);//a and d
        a2.show(b);//b and a
        a2.show(c);//b and a
        a2.show(d);//a and d
    }
    /*public static void show(Animal a){
        a.eat();
    }*/
}
class A{
    void show(A a){
        System.out.println("a and a");
    }
    void show(D d){
        System.out.println("a and d");
    }
}
class B extends A{
    void show(A a){
        System.out.println("b and a");
    }
    void show(B b){
        System.out.println("b and b");
    }
}
class C extends B{
}
class D extends C{
}

我们先看a2.show(c),首先a2是一个a类型的引用类型,在a2种寻找show(c)参数为c类型的方法,没有找到c类型的方法,于是到a2的超类寻找其方法,由于a类的超类是Object,也并没有show(c)这个方法,于是将c类型进行了提升,变成了b类型,b类型在a中也不存在,于是便转换成了a类型,a类型与A类中找到了方法,并由于A类型的show方法于B类型中进行了重写,于是便输出了b and a

其寻找的顺序是:this.show(O)  super.show(O)  this.show(super(O))  super.show(super(O))

 

当使用了上述方法进行了多态的实现之后,其子类就会自动将其的特有方法给丢弃掉了,然而我们现在想调用这个对象的特有方法怎么办?

答案是使用使用强制类型转换,而使用强制类型转换则会有可能出现类型转换异常,这个时候就需要使用instanceof运算符,使用方法:父类对象  instanceof  子类,若父类引用时子类类型时返回true,则可以使用强制类型转换

这种实现过程叫做向下转型