Java面向对象详解

2018-09-25  本文已影响0人  chonglingliu

Java OOP

什么是面向对象思想?

把一组数据和处理他们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance)实现类的的特化(specialization)/泛化(generalization),通过多态(polymorphism)实现基于对象类型的动态分派(dynamic dispatch). --- 来源于知乎(如何用一句话说明什么是面向对象思想?)

这个定义指出了面向对象的四个特点:抽象、封装、继承和多态

类和对象

对象

具有一组数据和处理这些数据的方法组成一个对象。例如:

对象 person

数据 姓名,年龄

方法 说话,吃饭,睡觉

类可以看成是对象的抽象,是可以生成众多对象的一个模板。例如我们有一个Person类,有姓名年龄两个数据。这就是个模板,它不代表一个人person,但是能够通过这个模板创造出众多person。

// 定义类
权限修饰符 class 类名 {
    属性
    方法  
}

public class Person {
    String name; //名字
    int age;     //年龄
    // 吃饭方法
    void eat() {
        
    }
    // 说话方法
    void speak() {
        
    }
}

构造函数(Constructor)

    > 注意:如果类有构造函数,则编译器不会在编译阶段添加默认构造函数。所以如果在类有有参数的构造函数但是没有无参数的构造函数的情况下,调用无参数的构造函数编译器会报错。
    > ![](https://img.haomeiwen.com/i4401597/84dde9ec70a7f84c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/485) 

static关键字

static关键字可以修饰类、变量、方法和代码块。被static修饰的成员属于类,而不是对象。
由于static修饰的属性是公共属性,属于类。可以通过**“类.属性名”** 的方式进行获取和修改。例如

```
Person.industry = "music";              // 修改
System.out.println(Person.industry);  // 获取 
```

继承(Inheritance)

继承是指一个类获取另外一个类的属性和方法的过程,继承的主要目的是复用代码。获取另外一个类的特性的类被称为子类,而特性被另外一个类利用的类则相对应称为父类。

super

super是一个Java关键字,相当于是指当当前对象的直接父类中的成员

方法重载(Method Overloading)

方法重载是指一个类可以有多个方法名相同但是方法的参数个数或者参数类型不同的多个方法存在,和构造函数可以有多个类似

绑定(binding)

绑定是指将一个方法的调用与方法所在的类关联起来。Java中的绑定分为静态绑定和动态绑定,又被称作前期绑定和后期绑定。

多态性(Polymorphism)

多态字面意思就是多种状态,例如同样的一个方法具有不同功能的特性,多态也可以分为编译时多态和运行时多态。

扩展:抽象类的抽象方法和接口也是实现多态的两种方式,会在接下来的章节详细介绍。

抽象类(Abstract Class)

abstract关键字修饰的类就是抽象类(Abstract Class),抽象类里面可以有抽象方法(没有方法体)也可以有普通方法。但是普通类里面不能定义抽象方法。

注意:抽象类不能被实例化,就是说不能被用来创建对象。

```
abstract class Animal {
    abstract void sound(); // 这个方法让子类去自己实现
    
    void anothermethod() { // 普通的方法
        System.out.println("another method");
    }
}

class Dog extends Animal {
    @Override
    void sound() { // 必须实现这个方法
        System.out.println("wang wang wang");
    }
}
```

接口(Interface)

接口和类相似但是又不是一个类,接口的方法都不能有实现(完全抽象),接口的属性访问修饰是public,static,final

封装(Encapsulation)

封装包括隐藏数据和功能的具体实现,是将该类中所有对象的属性和行为隐藏起来,并为其他对象提供一些访问的方法。例如:把属性定义为私有的,定义一些外部类能访问的方法对私有属性进行操作;再例如把Person类的speak功能做为一个方法,外部直接调用speak功能。

public class Person {
    // 一些私有的属性,外部类不能访问
    private int age;
    private String name;
    
    // 定义一些外部类能访问的方法,对私有属性进行操作
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public void speak() {
        System.out.println(this.name);
    }
    
    public static void main(String[] args) {
        
        Person person = new Person();
        person.setName("Johnny");
        person.setAge(18);
        System.out.println(person.name);
        System.out.println(person.age);
        
        person.speak();
    }
    
}
- **static引包**      
    
    我们普通引包主要是为了复用其他包的public的类和接口,而static引包是为了使用其他包定义的静态的属性和方法,而不需要在属性和方法前面加上类名。
    `java.lang.Math`包中有很多数学计算的静态方法,例如sqrt,tan等,正常的引用方法如下:
    
    ```
    // 普通引包-- import包名
    import java.lang.Math;
    
    public class Demo {
        
        public static void main(String[] args) {
            // 如果是普通引包,使用类.静态方法和类.静态属性
            double number1 = Math.sqrt(4);
            System.out.println(number1); // 2.0
        }
        
    }
    ```
    
    ```
    // 静态引包--在import 和 包名.类名 中间加上 static 关键字
    import static java.lang.Math.*;
    
    public class Demo {
        
        public static void main(String[] args) {
            // 如果是静态引包,可以直接使用静态方法和静态属性
            double number1 = sqrt(4);
            System.out.println(number1); // 2.0
        }
        
    }
    ```
    
    > 说明:当使用类的静态属性或者静态方法比较频繁时候比较实用,例如需要频繁进行数学计算方法时建议用static引入。静态引入的缺点是对包的信息不了解,容易造成冲突和混淆。
    
- ** 关于包的两点说明**

    1. 多个包中可能出现命名冲突,此时使用时需要用**包名.类名**。
        例如A包里面有一个Person类,B包里面也有一个Person类。此时不能申明引入两个Person类,因为有命名冲突。
        
        ```
        import A.Person;
        import B.Person; // 会有编译错误,因为命名冲突了
        ```
        
        可以用通配符引入的方式即引入包下的所有类去解决,使用时候需要指明包名。
        
        ```
        import A.*;
        import B.*;
        
        public class PackageDemo {
            
            public static void main(String[] args) {
                
                A.Person personA = new A.Person();
                B.Person personB = new B.Person();
                
            }
        }
        ```
        
    2. 用通配符引入的时候需要特别注意,假设有个A包,A包下面有Person类,A包下面还有一个B包,B包下面有Dog,Cat两个类。如果用 `import A.*;` 此时只引入了Person类,并未引入了B包下的Dog和Cat类。如果使用`import A.B.*;`, 此时引入的是Dog和Cat类。如果要把三个类都引入需要使用`import A.*; import A.B.*;`

final

final关键字能修饰属性,方法和类,接下来进行详细介绍。

上一篇下一篇

猜你喜欢

热点阅读