目录
“面向对象的方法主要是把事物给对象化,包括其属性和行为。面向对象编程更贴近实际生活的思想。总体来说面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用就是面向对象,(万物皆对象)。
其本质就是:以类的方式组织代码,以对象的组织(封装)数据。
什么是类:类是一种抽象的数据类型,他是对某一类事物的整体描述/定义,但是并不代表某一具体的事物。例如:手机,电脑等等;又比如Person类、Pet类、Cat类等等。
什么是对象:对象是抽象的具体实例。比如张三是人的一个具体实例,旺财是一个狗的具体实例。
能够体现出特点,展现出功能的具体实例,而不是一个抽象的概念。
1.使用new关键字创建对象,除了分配内存空间以外还会个创建好的对象进行默认初始化以及对类中的构造器进行调用。
通常情况下一个类能不能直接使用,需要根据一个类创建一个对象,才能使用,因此我们需要创建一个对象来调用这个类。
创建类的步骤
1)导包:
格式:import包名称.类名称;
对于同一个包的情况下,可以省略导包语句
2)创建:
格式:
类名称 对象名=new 类名称();
3)使用:
(1)成员属性:
格式: 对象名.成员变量名;、
(2)成员方法:
格式: 对象名.成员方法名(参数);
定义一个标准类(包括如下四个部分)
(1) 所有的成员变量都用private修饰、
(2) 每个成员变量都有getxxx()detxxx()方法
(3) 有一个无参构造
(4) 有一个全参构造
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- //一个项目只存在一个main方法
- public static void main(String[] args) {
- /*类:抽象的、需要实例化
- 类实例化后会返回一个自己的对象
- students对象就是Students的一个具体实例
- */
- Students students= new Students();
- students.name = "张三";
- students.age=20;
- System.out.println(students.name+students.age);
- }
- //属性
- String name;
- int age;
-
- //方法
- void stu(){
- //this代表这个类 指向型
- System.out.println(this.name+"学生在学习");
- }
类中的构造器也叫构造方法,在进行创建对象的时候必须进行调用。并且每一个类中都隐藏一个无参构造。
格式:public 类名称(形参 实参){
方法体
}
构造器:
1.和类名必须相同
2.没有返回值
作用:
1.new的本质就是在调用构造方法
2.初始化对象的值
注意点:
定义有参构造之后,如果还想用无参构造的话,那么就必须显示的定义一个无参构造。
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- //一个项目只存在一个main方法
- public static void main(String[] args) {
- Students students= new Students("代码贩子");
- System.out.println(students.name);
- }
- String name;
- //一个类及时什么也不写也会存在一个方法
- //定义一个构造器
- //实例化初始值
- /*
- 使用new关键字,必须使用构造器
- 用来初始化值
- */
- //无参构造
- public Students(){
- //代表的是上面的name
- this.name = "张三";
- }
- //有参构造
- //一旦定义了有参构造,无参构造必须显示定义
- public Students(String name){
- this.name = name;
- }
- //alt+inset可以快速构造
1.首先先在方法区把Demo01类的游戏额代码信息放进来。
2.主方法main()会被压入栈.。
3.一旦new会在方法区加载出Student这个类。
4.当等于通过Students A= new Students();生成一个A同学放入栈中(此时的A只是一个引用或者变量名)。
5.针对于这个对象A会在堆里面,通过这个模板new了一个A。
6.此时的action()方法其实调用了方法区中的action()方法,此时Students A= new Students();方法就完成了。
7.接下来给name、age进行赋值。
8.将方法区的Demo01中的常量池中的值丢个堆中A进行name和age的赋值,此时A.name = "代码贩子、"; A.age = 24;以及A.action();中的值就赋完了,此时这个对象A的堆中就有这些值了,此时就可以使用它了。
9.如果出现了同学B就相当于当等于通过Students A= new Students();生成一个A同学放入栈中(此时的A只是一个引用或者变量名)。
10.针对于这个对象A会在堆里面,通过这个模板new了一个B。
11.此时的action()方法其实调用了方法区中的action()方法,此时Students。 B= new Students();方法就完成了,此时后面的操作相同。
注意:静态方法区所有带static关键字的东西一开始就在这个地方,和类一起加载的,类一加加载,它就加载了。所有的对象都可以加载它。

- /**
- * @Author代码贩子、 --南京邮电大学
- */
- //一个项目只存在一个main方法
- public static void main(String[] args) {
- Students A= new Students();
- A.name = "代码贩子、";
- A.age = 24;
- System.out.println(A.name+A.age+A);
- A.action();
- }
- public String name;
- public int age;
- //无参构造
- void action(){
- System.out.println("疯狂学习Java编程知识!");
- }
定义(自己理解):该露的露,该藏的藏。将一些较为复杂的内部结构进行隐藏,将一些简单的(比如接口)该暴露给用户的东西暴露出来,比如电视机的外观等等。大部分程序的细节都应该藏起来。我们设计的程序应该追求”高内聚,低耦合“(也就是系统内部的数据操作应该由自己完成,不允许外部进行干预;仅仅暴露少量的方法给外部来进行使用)。
一旦使用了private进行修饰,本类当中可以随意访问,但是超出了本类就不可以访问了。
间接访问private成员变量,就定义一对getxxx()setxxx()方法
对于set来说,不能有返回值,参数类型和成员变量对应
对于get来说,不能有参数,必须有返回值类型,并且返回值类型与成员变量对应。
封装的意义:
1.提高程序的安全性,保护数据。
2.隐藏代码的关键细节(以s1.setAge(24)来说,用户根本不知道里面干了什么,只有我们程序员才知道);。
3.统一接口。
4.提高了系统的可维护性。
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- Students s1 = new Students();
- /*
- s1.name;无法进行调用,变量被private被私有了
- 如果换成public公有的关键字才可以被调用
- */
- s1.setName("代码贩子、");
- s1.setAge(24);
- s1.setSex('男');
- System.out.println(s1.getName());
- System.out.println(s1.getAge());
- System.out.println(s1.getSex());
- }
- //private关键字为私有化
- private String name;//名字
- private int age;//年龄
- private char sex;//性别
- /*
- 想要解决主程序中的s1.name被调用的问题就需要提供一些可以操作这个属性的方法
- 解决办法就是提供一些public的get、set方法
- */
- //获得这个数据
- public String getName(){
- return this.name;
- }
- //给这个数据设置值
- public void setName(String name){
- this.name=name;
- }
- //快捷键
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- if (age<100&&age>0) {
- this.age = age;
- }else {
- this.age=3;
- }
- }
-
- public char getSex() {
- return sex;
- }
-
- public void setSex(char sex) {
- this.sex = sex;
- }
定义:继承的本质就是对某一批类进行的抽象,从而实现对现实世界最好的建模。
关键字:extends。意思为”扩展“,子类是父类的扩展。
修饰符的级别;public>protected>default(或者是不写)>private
Java中的类只有单继承的关系,没有双继承的关系(相当于一个父类可以有多个子类,但是多个子类只能以有一个父类)。
| 级别(由大到小) | ||||
| 关键字名称 | Public | protected | default | private |
| 作用域 | 可以被该类的和非该类的任何成员访问 | 子类可以使用父类中,其他的不可以,它相当于传递给子类的一种继承的东西。 | 一个包内可以访问,如果不在一个包内,即使是继承关系,子类也无法访问。 | 只有该类可以直接调用,其余类想要调用需要使用get()set()方法 |
继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,用关键字extends来表示。
子类和父类之间,从意义上讲应该具有”is a“的关系。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- Student student =new Student();
- //子类可以继承父类的所有方法
- /*
- 父亲说我有钱了
- 儿子继承了父亲的财产
- 儿子也说我有钱了
- */
- //子类没有任何的说明
- //接收这个方法
- student.money();
- //子类可以继承父类的所有属性
- //父类中父亲姓代码,那么子类中的儿子也会继承叫代码
- System.out.println("我跟随父亲的姓氏姓:"+student.xingshi);
- /*
- 父类中的父亲有十个小妾,但是用private关键字进行私有了,只属于父类自己
- 儿子不管是出于道德还是出于代码逻辑都不能进行继承
- System.out.println(student.xiaoqie);
- 因此子类无法进行继承和调用
- */
- /*
- 出于道德不继承父亲的小妾,但是父亲有十件古董,但是被父亲私有制了,那么我们要想获得必须经过父亲的同意
- 让父类提供一些public的get、set方法
- */
- System.out.println("父亲同意将私有的古董给我:"+student.getGudong()+"件");
- }
- }
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- Student student =new Student();
- //子类可以继承父类的所有方法
- /*
- 父亲说我有钱了
- 儿子继承了父亲的财产
- 儿子也说我有钱了
- */
- //子类没有任何的说明
- //接收这个方法
- student.money();
- //子类可以继承父类的所有属性
- //父类中父亲姓代码,那么子类中的儿子也会继承叫代码
- System.out.println("我跟随父亲的姓氏姓:"+student.xingshi);
- /*
- 父类中的父亲有十个小妾,但是用private关键字进行私有了,只属于父类自己
- 儿子不管是出于道德还是出于代码逻辑都不能进行继承
- System.out.println(student.xiaoqie);
- 因此子类无法进行继承和调用
- */
- /*
- 出于道德不继承父亲的小妾,但是父亲有十件古董,但是被父亲私有制了,那么我们要想获得必须经过父亲的同意
- 让父类提供一些public的get、set方法
- */
- System.out.println("父亲同意将私有的古董给我:"+student.getGudong()+"件");
- }
- }
- //学生(派生类;Person的子类)继承了人的所有关系
- public class Student extends Person {
- }
- //教师(派生类;Person的子类)继承了人的所有关系
- public class Teacher extends Person {
- }
-
supper代表队的是在子类中调用父类中的属性或者是方法。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- Student student = new Student();
- student.name("代码贩子本人");
- }
- }
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public class Person extends Object {
- protected String name = "代码贩子、";
- }
- public class Student extends Person {
- private String name = "小代码贩子、";
- void name(String name){
- System.out.println(name);//代表的是方法传进来的String name
- System.out.println(this.name);//代表的是private私有制的name
- System.out.println(super.name);//代表的是父类protected受保护的name
- }
- }
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- Student student = new Student();
- }
- }
-
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public class Person extends Object {
- public void say(){
- System.out.println("我是父亲");
- }
- }
- public class Student extends Person {
- public void say(){
- System.out.println("xusheng");
- }
- public void test(){
- say();
- this.say();
- super.say();
- }
- }
如果父类的构造器换成私有制的关键字属性,那么原本的子类就无法使用super关键字来进行方法的调用。
这里参杂了一个代码位置的问题。
首先在我们的子类以及父类都会隐藏一个默认的无参构造器。相当于在Person类中有个public Person() { System.out.println("父类无参执行了!"); },在子类中有个public Student() { System.out.println("子类有参执行了!"); }。此时在new Studengt();的时候执行的结果如下所示:

因为在子类中调用子类的构造器之前还隐藏了一段代码: super()。
super();的代码只能放在子类构造器第一行,如果和System.out.println("子类有参执行了!");互换位置就会报错。因为new Studengt();的同时将父类的也new了。
this关键字也是如此,急啊如在子类中急啊如一个有参构造器,public Student(String name) { this.name = name; },此时调用的时候this("代码贩子、");也只能放在无参构造器的额第一行。此时苏果想要放super关键字也必须放第一行,this关键字就会报错。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- Student student = new Student();
- }
- }
-
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public class Person extends Object {
- //走一个无参构造器
- public Person() {
- System.out.println("父类无参执行了!");
- }
- void say(){
- System.out.println("我是父亲");
- }
- }
- public class Student extends Person {
- private String name;
-
- public void say(){
- System.out.println("xusheng");
- }
- public Student() {
- /*
- 在调用构造器的时候,要么调用父类要么调用子类,必须保证在构造器的第一个
- 正常情况下super();不写也是正常的,会默认的调用无参。
- */
- this("代码贩子、");//调用本类有参构造器,必须放在子类的第一行。
- //super();//调用父类无参构造器,必须放在子类的第一行。(隐藏)
- System.out.println("子类有参执行了!");
- }
- public Student(String name) {
- this.name = name;
- }
-
- public void test(){
- say();
- this.say();
- }
- }
假如父类中的无参构造我们不写,只写了有参构造,那么在子类中就无法进行父类无参构造的调用,不仅如此,子类中的无参也会报错。南无说我就想要调用父类中的有参构造,那么就需要在子类无参构造中利用super("代码贩子、");的形式一步步的调用。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- Student student = new Student();
- }
- }
-
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public class Person extends Object {
- public String name;
- //走一个有参构造器
-
- public Person(String name) {
- this.name = name;
- }
-
- void say(){
- System.out.println("我是父亲");
- }
- }
- public class Student extends Person {
- private String name;
-
- public void say(){
- System.out.println("xusheng");
- }
- public Student(){
- super("代码贩子、");
- }
-
- public void test(){
- say();
- this.say();
- }
- }
因此我们封装的时候无论一个类怎么写,在写的时候一般只要重写了有参构造,一般都会加上无参构造。
super注意点:
1.super是调用父类的构造方法,必须写在构造方法的第一个。
2.super必须只能出现在子类的方法或者3.构造方法中。
3.this和super不能同时调用构造方法。
VS this注意点:
1.代表的是本身调用者这个对象。
2.代表父类对象的应用。
前提:
2.没有继承的前提下也可以使用。
3.只能在继承条件下才可以使用。
构造方法:
this();调用的是本类的构造。
super();调用的是父类的构造。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- /*
- 方法的调用只和定义的数据类型有关
- */
- A a = new A();
- a.test();//走的是A类的静态方法
-
- B b = new A();//父类的引用可以指向子类
- b.test();//走的是B类的静态方法
- }
- }
- //A类继承了B类
- public class A extends B {
- public static void test(){
- System.out.println("A=>test()");
- }
- }
- //重写都是方法的重写,和属性无关
- public class B {
- public static void test(){
- System.out.println("B=>test()");
- }
- }
此时把A和B中的静态方法去掉,利用快捷键在A类中进行重写,默认走的都是B的方法。如果在A类中重写自己的方法,得到的都是A的方法。所以可以得出一个结论,就是静态方法和非静态方法有区别。
原因是B b = new A();//非静态方法中子类重写了父类的方法。此时才叫重写
并且重写的时候修饰符还必须是public的,不能是私有的。
只有子类继承了父类才能重写,并且是子类重写父类的方法。
- public class A extends B {
- @Override
- public void test() {
- super.test();
- }
- }
- //重写都是方法的重写,和属性无关
- public class B {
- public void test(){
- System.out.println("B=>test()");
- }
- }

- public class A extends B {
- @Override
- public void test() {
- System.out.println("A=>test()");
- }
- }
- //重写都是方法的重写,和属性无关
- public class B {
- public void test(){
- System.out.println("B=>test()");
- }
- }

总结(重写):
1.必须有继承到关系并且还是子类重写父类的方法,和属性无关。
特点:
1.方法名必须相同。
2.参数列表必须相同。
3.修饰符范围可以扩大。
4.抛出的异常:可以被缩小但是不能扩大。
总结:子类的方法和父类必须要一致,方法体不同。
为什么需要重写?
父类的功能:子类可能不一定需要,或者是不一定满足!
定义:同一个方法可以根据发送对象的不同而采用多种不同的行为方式。一个对象的实际类型是确定的,但可以指向对象的引用类型很多。
多态可以让程序变得更灵活。
一个对象的实际类型是确定的,比如new Student(),new Person();但是可以指向这个类型的引用类可以是任意的。比如:Person s2 = new Student(); Object s3 = new Student()。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- /*
- 一个对象的实际引用类型是确定的,比如:
- new Student()
- new Person()
- */
- Student s1 = new Student();//子类指向的引用
- /*
- 子类能调用的方法都是自己的或者是父类的
- */
- //父类的引用可以指向子类(有父子关系就可以 ,比如用String肯定不行,因为没有指定的关系。)
- Person s2 = new Student();//父类指向的引用
- /*
- 父类型虽然可以指向子类,但是不能调用子类独有的方法
- */
- Object s3 = new Student();
-
- s2.run();//运行结果为run,因为子类重写了父类的方法,执行的为子类的方法
- s1.run();
- s1.eat();
- //对象能执行哪些方法,主要看对象左边的类型,和右边的关系不大。
- /*
- ((Student)s2).eat();
- 强制转换后可以进行调用
- */
- (s2.eat());//无法调用是因为 Person s2 = new Student();虽然new了Student()但不能使用Student()方法,要看Person里面有没有,有的话才能用。
- // 子类重写了父类的方法,执行的为子类的方法。子类和父类的方法都有的话,子类没有重写方法,就调用父类的,如果重写的话就带哦用子类的。
- }
- }
-
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public class Person extends Object {
- public void run(){
- System.out.println("run");
- }
- }
- public class Student extends Person{
- @Override
- public void run() {
- System.out.println("son");
- }
- public void eat(){
- System.out.println("eat");
- }
- }
注意事项:
1.首先多态是方法的多态,跟属性无关。
2.要有关系(父子类),不然的话会出现类型转换异常。
存在条件:
1.要有继承的关系。
2.方法需要重写(static属于类,不属于实例、final输入常量,在常量池,private私有的不能重写就不能进行多态)。(假如子父类都有run方法,那么子类没有重写方法,就调用父类的,如果重写的话就带哦用子类的)。
3.父类引用指向子类对象、
作用:instanceof关键字可以判断两个类之间是否存在父子关系。
1.父类引用指向子类的对象。
2.子类转换为父类(向上转型),不用强制转换。
3.父类转换为子类(向下转型),强制转换后会丢失方法。
4.方便方法的调用,减少重复的代码,提升代码的利用率并且使代码变得更简洁。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- //Object>String
- //Object>Person>Student
- //Object>Person>Teacher
- //System.out.println(A instanceof B);
- //A和B是否有继承关系
- Object object = new Student();
- System.out.println(object instanceof Student);//true
- System.out.println(object instanceof Person);//true
- System.out.println(object instanceof Object);//true
- System.out.println(object instanceof Teacher);//false
- System.out.println(object instanceof String);//false
- Person person = new Student();
- System.out.println(person instanceof Student);//true
- System.out.println(person instanceof Person);//true
- System.out.println(person instanceof Object);//true
- System.out.println(person instanceof Teacher);//false
- //System.out.println(person instanceof String);//编译错误
- }
- }
-
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public class Person extends Object {
- public void run(){
- System.out.println("run");
- }
- }
- public class Student extends Person{
- @Override
- public void run() {
- System.out.println("son");
- }
- public void eat(){
- System.out.println("eat");
- }
- }
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public static void main(String[] args) {
- Person student = new Student();
- //因为这里是Person类型的student
- //student.eat();
- //将Person类型的student的对象转换成student类型,我们就可以使用student类型的方法了。
- Student obj = (Student) student;
- //这样就可以使用低一层的方法了
- obj.eat();
- //第二种写法((student)obj).eat();
- /*
- 由低转高(子类转换成父类)
- 可能会丢失一些方法
- */
- Person person = new Student();
- //丢失一些方法
- //person.eat();
- }
- }
-
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- public class Person extends Object {
- public void run(){
- System.out.println("run");
- }
- }
- public class Student extends Person{
- @Override
- public void run() {
- System.out.println("son");
- }
- public void eat(){
- System.out.println("eat");
- }
- }
1.static静态变量在类中是共享的。
2.非静态方法可以访问本类中的所有静态方法。
3.静态方法可以调用本类中所有的静态方法。
原因:因为静态的方法是和mian方法一起加载出来的,加载之前还没有普通的方法,所以就无法调用。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- /*
- static静态变量在类中是共享的
- */
- private static int name;//静态变量
- private double age;//非静态变量
- public static void main(String[] args) {
- System.out.println(name);//直接可以调用
- System.out.println(age);//不可以直接调用
- Demo01 demo01 = new Demo01();
- //通过对象调用
- System.out.println(demo01.age);
- System.out.println(demo01.name);
- }
- }
1.静态代码块(最早的执行);静态代码块只在一开始执行一次并且后面将不再执行。
2.匿名代码块在对象一创建的时候,就先走匿名代码块,然后再走构造器;作用:赋初始值。
3.构造器最后执行。
- public class Demo01 {
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- {
- //匿名代码块
- //作用:赋初始值
- System.out.println("匿名代码块");
- }
- static {
- //静态代码块(最早的执行)
- System.out.println("静态代码块");
- }
-
- public Demo01(){
- //构造器(最后执行)
- System.out.println("构造器");
- }
- public static void main(String[] args) {
- Demo01 demo01 = new Demo01();
- System.out.println("-------------分隔符-------------");
- /*
- 因为静态代码块只执行一次
- 对象一创建的时候,就先走匿名代码块,然后再走构造器
- 静态代码块只在一开始执行一次并且后面将不再执行
- */
- Demo01 demo02 = new Demo01();//此时执行的时候静态代码块就没了
- }
- }

抽象类定义;在普通类的结构里面增加抽象方法的组成部分。
抽象方法定义:是指没有方法体的方法。
关键字为:abstract。
注意:
1.不能new这个抽象类,只能靠它的子类进行实现。
2.抽象类中可以写普通的方法。
3.抽象方法必须在抽象类中。
-
- /**
- * @Author代码贩子、 --南京邮电大学
- */
- //抽象类
- public abstract class Person {
- //约束 有人帮我们实现
- //只有方法的名字,没有方法的实现
- public abstract void work();
- }
- //抽象类的所有方法,继承了它的子类,都必须要实现它的方法,除非子类本身也是一个抽象类。
- public class Student extends Person{
- @Override
- public void work() {
-
- }
- }
接口的定义:简单来说为某种特征的约定。
关键字:interface。
1.类可以实现接口 implements
2.实现了接口的类,就需要重写接口中的方法
3.利用接口实现多继承,但是与继承关系无关。
- //接口定义的关键字interface
- //接口都需要有实现类
- public interface userService {
- //接口中的所有定义都是抽象的 public abstract
- void add(String name);
- void delete(String name);
- void update(String name);
- void query(String name);
- }
- public interface timeService {
- void timer();
- }
- //类可以实现接口 implements
- //实现了接口的类,就需要重写接口中的方法
- //利用接口实现多继承
- public class userServiceImpl implements userService,timeService{
- @Override
- public void add(String name) {
-
- }
-
- @Override
- public void delete(String name) {
-
- }
-
- @Override
- public void update(String name) {
-
- }
-
- @Override
- public void query(String name) {
-
- }
-
- @Override
- public void timer() {
-
- }
- }
总结:
1.约束。
2.定义一些方法,让不同的人实现功能。
3.接口不能被实例化,并且接口没有构造方法。
4.implements关键字可以实现多个接口。
5.必须要重写接口中的方法。