面向对象是Java编程的核心概念,如果不能充分了解面向对象的思想,那么会给你在实际的项目开发过程中,带来很多业务设计上的困扰。
一、构造器
我们在设计完一个类,在使用这个类去创建对象实例的时候,有些场景是需要对实例做初始化操作的,那么Java中提供了构造器来满足这方面要求。
1、原则
- 名字必须与所在类名称一致
- 不能有返回值和返回值类型
- 构造器也可以重载(参数列表不一样)
- 类在设计时,如果没有写构造器,Java是会为类自动生成一个无参数构造器。
- 如果定义类的有参数构造器,则不会创建无参数构造器。【建议手动创建一个无参数构造器】
2、 构造器的多种形式
默认无参数构造器:
class Rock{
	printme(){
		System.out.print("printme");
	}
}
Rock r=new Rock();
有参数构造器:
class Rock {
    Rock(String name) {
        System.out.print("这是一个有参构造器:" + name);
    }
}
Rock r = new Rock("IT飞牛");
//这是一个有参构造器:IT飞牛
构造器重载:
class Rock {
    Rock(String name) {
        System.out.println("这是一个有参构造器,姓名:" + name);
    }
    Rock(String name, int age) {
        this(name);//这里使用this调用其他构造器,复用
        System.out.println("这是一个有参构造器,年龄:" + age);
    }
}
Rock r = new Rock("IT飞牛", 18);
//这是一个有参构造器,姓名:IT飞牛
//这是一个有参构造器,年龄:18
二、重载
类中的一个方法,有些场景下需要根据不同的情况,做不同的操作,当然我们可以直接定义不同的方法就能实现。但是有些时候的确是同类型的操作,方法名最好是一样的,这时候我们可以使用重载来实现。
类中的重载主要是根据方法传入的参数类型列表,去自动识别调用不同的方法执行。
下面提供了同方法名,但是不同参数的案例:
package com.itfeiniu.hello;
public class HelloWorld {
    public static void main(String[] args) {
        Rock r = new Rock();
        r.say();
        r.say("你好");
        r.say("你好", 3);
        r.say(3, "你好");
    }
}
class Rock {
    void say() {
        System.out.println("啥都没说");
    }
    void say(String msg) {
        System.out.println("说:" + msg);
    }
    void say(String msg, int num) {
        System.out.println(msg + ",被说了" + num + "遍");
    }
    void say(int num, String msg) {
        System.out.println("说了" + num + "遍," + msg);
    }
}
//啥都没说
//说:你好
//你好,被说了3遍
//说了3遍,你好
可以看到,不同的入参,调用了不同的同名方法。
涉及基本类型的重载,可能会由于变量类型提升,调用的方法有偏差。例如:Rock加入有个do方法,调用r.do(1)这个方法,参数会按照int类型去识别。请看下面案例:“
package com.itfeiniu.hello;
public class HelloWorld {
    public static void main(String[] args) {
        Rock r = new Rock();
        r.say(2);
        r.say((byte) 2);
    }
}
class Rock {
    void say(byte num) {
        System.out.println("这是byte");
    }
    void say(int num) {
        System.out.println("这是int");
    }
}
//这是int
//这是byte
三、this关键字
this就是一个变量,可以用在方法中,来拿到当前对象。
接触过js的小伙伴应该是比较好理解,java中的this的指向和js中的this的指向是一个原则:【谁调用,this就指向谁】
四、static的含义
static方法就是没有this的方法,在static方法内部不能调用this。并且在static内部不能调用非静态方法。
而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途,他很像全局方法。
五、super
可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
六、封装
合理隐藏 合理暴露
1、访问控制
java类中的方法或者属性,可以设置访问范围,修饰符是:private、protect、public。
-  private:该成员可以被该类内部成员访问; 
-  default:该成员可以被该类内部成员访问,也可以被同一包下其他的类访问; 
-  protected:该成员可以被该类内部成员访问,也可以被同一包下其他的类访问,还可以被它的子类访问; 
-  public:该成员可以被任意包下,任意类的成员进行访问。 
2、读写拦截器getter、setter
java中的读写拦截器是基于public方法来实现的。
package com.itfeiniu.hello;
public class HelloWorld {
    public static void main(String[] args) {
        Rock r = new Rock();
        r.setName("张三");
        System.out.println(r.getName());
        r.setAge(20);
        System.out.println(r.getAge());
    }
}
class Rock {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    private int age;
}
//张三
//20
可以使用IDEA快速生成getter和setting,如下图:
 .
.
七、实体类
实体类的特点:
- 这个类中的成员变量都要私有,并且要对外提供相应的getXxx,setXxx方法。
- 类中必须要有一个公共的无参的构造器。
下面Student类就是典型的实体类,整个类就是用来保存学生数据的,没有其他任何数据处理业务。一般实体类会配合实体类的操作类来使用,实体类存放数据,操作类StudentOperator使用实体类的数据做数据处理业务。
代码如下:
package com.itfeiniu.hello;
public class HelloWorld {
    public static void main(String[] args) {
        Student std1 = new Student("张三", 60);
        StudentOperator sto1 = new StudentOperator(std1);
        sto1.printPass();
        Student std2 = new Student("李四", 50);
        StudentOperator sto2 = new StudentOperator(std2);
        sto2.printPass();
    }
}
class StudentOperator {
    private Student student;
    public StudentOperator(Student student) {
        this.student = student;
    }
    public void printPass() {
        if (student.getScore() >= 60) {
            System.out.println(student.getName() + ",及格了");
        } else {
            System.out.println(student.getName() + ",没及格");
        }
    }
}
class Student {
    private String name;
    private int score;
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    public Student() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
}
七、继承
继承是实现软件复用的重要手段。
继承中最常使用的两个关键字是 extends 和 implements 。通过使用这两个关键字,我们能实现一个对象获取另一个对象的属性。
所有 Java 的类均是由 java.lang.Object 类继承而来的,所以 Object 是所有类的祖先类,而除了 Object 外,所有类必须有一个父类。
public interface Animal {}
public class Mammal implements Animal{
}
public class Dog extends Mammal{
}
Java不支持多继承,例如下面的写法是错误的:
public class extends Animal, Mammal{} 
但是我们可以用接口来实现(多继承接口来实现),代码结构如下:
//Apple.java
package com.itfeiniu.hello;
class Fruit {
    String color;
    int kg;
    String shape;
}
interface Fruit1 {
    public void eat1();
    public void travel1();
}
interface Fruit2 {
    public void eat2();
    public void travel2();
}
public class Apple extends Fruit implements Fruit1, Fruit2 {
    public Apple(String color, int kg, String shape) {
        this.color = color;
        this.kg = kg;
        this.shape = shape;
    }
    public void eat1() {
        System.out.println("eat1");
    }
    public void travel1() {
        System.out.println("travel1");
    }
    public void eat2() {
        System.out.println("eat2");
    }
    public void travel2() {
        System.out.println("travel2");
    }
}
//helloworld.java
package com.itfeiniu.hello;
public class HelloWorld {
    public static void main(String[] args) {
        Apple app = new Apple("red", 5, "circle");
        app.eat1();
        app.eat2();
        System.out.println(app.color);
    }
}
//eat1
//eat2
//red



















