面向对象
什么是面向对象
面向对象,英文名Object Oriented Programming(OOP),也就是面向对象编程。
面向对象编程的本质就是:以类的方式组织代码,以对象的形式封装数据。
什么是类,什么是对象
- 类是一种抽象的数据类型,它是对某一类事物的整体描述/定义
- 对象是某个类的具体事例
什么是抽象
抽象就是更关注事物的总体部分,忽略具体细节,将它们的共同特征归纳出来,抽出像的部分!
例:人都有名字和年龄,所以抽象出来有name和age两个属性,忽略具体的细节指每个人的名字和年龄都不同,但是我们不关注。
面向对象的三大特征
封装
封装是把类的数据包围起来,对数据的访问只能通过指定的方式。
优点:
- 提高程序的安全性,保护数据
- 对外提供了统一的接口
- 隐藏代码的实现细节
- 提高了系统的可维护性
继承
- 继承是类与类之间的一种关系
- 继承关系的两个类,一个为父类,一个为子类,使用关键字extends来表示,Object类是所有类的父类
- 子类和父类之间,从意义上讲应该具有"is a"的关系
- 类与类之间只能是单继承
- 父类中的属性和方法可以被子类继承,但是如果是private修饰的方法或者属性,子类是无法调用的
- 父类中的构造器是不能被子类继承的,但是子类的构造器中,会隐式的调用父类中的无参构造器(默认使用super关键字)。
多态
- 一个事物多种形态,在java中的表现就是 父类引用指向子类对象(即实际类型是子类,但是引用类型是父类)
- 多态的实现必须有继承,重写,向上转型三个条件,即必须有子类继承父类并重写父类的方法,然后调用时创建一个子类对象,但是他的引用类型是父类,例:Person person = new Student();
- 多态是方法的多态,属性没有多态的。以下几种方法不能提现出多态性:
- static方法,因为被static修饰的方法是属于类的,而不是属于实例的
- final方法,因为被final修饰的方法无法被子类重写
- private修饰的方法,子类因为权限问题无法调用重写
抽象类与接口
抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
接口
泛指供别人调用的方法或者函数,它是对行为的抽象。
区别:
-
抽象类的关键字是abstract class,接口的关键字是interface
-
抽象类是用来被继承的,继承的关键字是extends。接口是用来实现的,关键字是implements
-
接口中的所有方法都是抽象方法,默认以public abstract修饰的,接口中的常量都是默认以public static final修饰的
-
java中类的继承只能是单继承,但是接口可以多实现,所以我们用的更多的是接口
-
抽象类和接口都不能实例化,但是抽象类有构造器,接口没有
-
接口可以继承接口,而且可以多继承
public interface A{ public void testA(); } public interface B{ public void testB(); } public interface C extends A,B{ public void testC(); }
同样,实现C接口的类,也必须实现A接口和B接口中的方法!
内部类
顾名思义,就是在一个类中定义了另外一个类,就是内部类。
成员内部类
在A类中申明了一个B类,此B类就在A的内部,并且在成员变量的位置上,所以就称为成员内部类。(成员内部类中不能写静态属性和方法)
静态内部类
通过static修饰的内部类
局部内部类
在方法中定义的内部类
匿名内部类
没有名字的内部类。如果某个类只用一次,写这个类又很麻烦,就不需要在类中先定义一个内部类,而是等待需要用的时候,临时实现这个内部类。
- 实现接口的匿名内部类
/**
* 包含两个方法的HelloWorld接口
*/
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
- 匿名子类(继承父类)
public class AnimalTest {
private final String ANIMAL = "动物";
public void accessTest() {
System.out.println("匿名内部类访问其外部类方法");
}
class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public void printAnimalName() {
System.out.println(bird.name);
}
}
// 鸟类,匿名子类,继承自Animal类,可以覆写父类方法
Animal bird = new Animal("布谷鸟") {
@Override
public void printAnimalName() {
accessTest(); // 访问外部类成员
System.out.println(ANIMAL); // 访问外部类final修饰的变量
super.printAnimalName();
}
};
public void print() {
bird.printAnimalName();
}
public static void main(String[] args) {
AnimalTest animalTest = new AnimalTest();
animalTest.print();
}
}
参考博客