1.面向对象概述
1.1.类与对象的关系
有对象吗,没有的话我给你new一个!
对象顾名思义就是一个个的个体,当所有的个体,例如人的总称为人类,这一类的生物或者物品。人类是对人这种个体的抽象化,不会说你是个人类,而是说你是个人,所以人就是人类的具体实现。
简而言之,类是对象的抽象化,对象是类的具体实现。
正所谓Java主打的万物皆对象。
public class Person{
private String name;
private int age;
private String gender;
public Person(String name, int age, String gender){
this.name = name;
this.age = age;
this.gender = gender;
}
public void say(){
System.out.println("hello");
}
public static void main(String[] args){
Person p = new Person("张三", "22", "男");
p.say();
}
}
在上面代码中,类Person就是人的一种抽象化,每个人都有姓名、年龄、性别等属性和一些动作,比如说等。在main方法中我们使用关键字new将类具体化为一个对象,这个对象名张三、22岁、男性,并且说了hello。
1.2.类的具体描述
类Person中有属性name、age、gender等,方法say等。还有个比较特殊的方法public Person(...),这个方法就是类的构造器。
构造方法又成为构造器,和一般的方法不同的是:
- 没有返回值(没有返回类型,也没有void)
- 方法名和类名一样
一个类可以有多个构造方法,这是后面要说到的重载。
2.面向对象的三大特性
面向对象程序设计的优点:
- 可扩展
- 可重用
缺点:
- 复杂程度较高
2.1.继承
继承就是子类继承父类的特征和行为,得到父类的实例变量和方法。例如猫和狗都是动物,可以继承动物的一些通用特征和行为。
为什么需要继承?
如果没有继承,当我们写猫和狗的类时:
public class Cat {
private String name;
private int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name+"吃东西");
}
public void sleep() {
System.out.println(name+"睡觉");
}
}
public class Dog {
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name+"吃东西");
}
public void sleep() {
System.out.println(name+"睡觉");
}
}
发现我们写了很多重用的代码,比如属性name、age和方法eat、sleep等。
如果使用继承代码将变成怎么样呢?
public class Animal {
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(name+"吃东西");
}
public void sleep() {
System.out.println(name+"睡觉");
}
}
public class Cat extends Animal {
public Cat(String name, int age) {
super(name, age);
}
}
public class Dog extends Animal {
public Dog(String name, int age) {
super(name, age);
}
}
我们发现只需要写一个父类,子类就具有父类的属性和方法了,这样我们就不需要写那么多重复的代码了,提高了代码的复用性。
总结以下:
- 子类拥有父类的非private的属性、方法,这里private之前说过,所修饰的只能在同一个类中可见
- 子类可以对父类进行扩展
- 子类可以重写父类的方法
- Java中不支持多继承
重写和重载:
- 重写(override):猫和鱼都继承了动物类,如果动物类有一个方法叫run(),对于猫来说使用四肢奔跑,对于鱼来说使用鱼鳍游动。这时我们需要重写父类的方法:
public class Person {
public void run() {
System.out.println("动物跑起来了");
}
}
public class Cat {
@Override
public void run() {
System.out.println("猫跑起来了");
}
}
public class Fish {
@Override
public void run() {
System.out.println("鱼游起来了");
}
}
- 重载(overload):同一个类中,方法名相同,参数不同,返回值可以相同或不同。
public class Animal {
public void test() {}
public void test(int num) {}
public void test(String str) {}
public void test(int num, String str) {}
public void test(String str, int num) {}
}
2.2.多态
多态就是同一个行为具有不同的表现形式。
多态分类:
- 编译时多态:静态的,主要是方法的重载
- 运行时多态:动态绑定实现的,例如父类的引用指向子类的对象
实现多态的必要条件:
- 继承
- 重写
- 向上转型:父类的引用指向子类的对象
多态的优点:
- 消除耦合关系
- 可扩展性
- 简单易用
多态的实现方式:
- 重写
- 接口:可多实现接口,解决单继承的缺陷
public interface Animal {
public void run();
}
public class Cat implements Animal {
@Override
public void run() {
System.out.println("猫趴");
}
}
- 抽象类和抽象方法:抽象类中可以存在非抽象方法,抽象方法一定存在于抽象类中,抽象方法只声明不实现,继承的子类必须实现抽象类中的抽象方法
public abstract Animal {
public abstract void run();
}
public class Cat extends Animal {
@Override
public void run() {
System.out.println("猫趴");
}
}
2.3.封装
封装将类的实现细节隐藏,以保证程序和数据不受外部干扰,保护信息。
优点:
- 保护类中的东西,隐藏信息,实现细节
- 良好的封装可以减少耦合
- 类内部结构可以自由修改
- 可以精确控制类成员
public class Person {
private String name;
private int age;
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,然后对外提供public方法进行赋值和取值。