面向对象(封装,继承,多态)
封装性:把相关的数据封装成一个"类"组件
继承性:是子类自动共享父类属性和方法,这是类之前的一种关系。
多态性:增强软件的灵活性和重用性。
类:模板,图纸。类中定义对象的属性数据(成员变量),方法(成员方法),类中第一次使用时会加载到方法区。
对象:从模板中创建的具体实例,实例是数据的打包。
引用变量:理解成遥控器,保存一个实例的内存地址。
构造方法:新建实例对象时,立即执行的一个特殊方法;构造方法必须和类同名,并且没有返回值类型。
类的创建和使用
public class Test1{
public static void main(String[] args){
Person p = new Person();
//设置属性值
p.name = "list";
p.age = 12;
p.sex = "男";
//调用方法
p.eat();
p.sleep();
}
class Person{
//属性--成员变量
String name;
int age;
String sex;
//行为--方法
void eat(){
System.out.println("eat...");
}
void sleep(){
System.out.println("sleep...");
}
}
}
封装性
封装是指隐藏对象的属性和实现细节,仅仅对外提供公共的访问方法。
好处:提高安全性;提高重用性。
private关键字
是一个权限修饰符,用于修饰成员变量和成员函数,被私有化的成员只能在本类中访问。想要修改只能对外提供公共的get和set方法。
public class Student{
private String name;
private int age;
//设置公共的访问方法
//设置公共的赋值方法
public void setName(String n){
name = n;
}
//设置公共的取值方法
public void getName(){
return name;
}
public void setAge(int age){
age = a;
}
public void getAge(){
return age;
}
class demo{
public static void main(String[] args){
Students s = new Student();
//利用setXxx()给属性赋值
s.setName("zhangsan");
//利用getXxx()给属性取值
System.out.println(s.getName());
}
}
}
**练习1:创建Teacher类,并创建Teacher对象测试**
老师事物:设置特性和功能
特征:姓名、年龄、住址
功能:讲课
测试:
创建Teacher对象
调用老师的属性和功能
修改老师的属性
package com.test;
public class Teacher {
public static void main(String[] args) {
Tea t = new Tea();
t.setAddr("beijing");
t.setAge(12);
t.setName("jack");
System.out.println(t);
t.teachers();
}
}
class Tea{
private String name;
private int age;
private String addr;
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;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public void teachers() {
System.out.println("讲课");
}
@Override
public String toString() {
return "Tea [name=" + name + ", age=" + age + ", addr=" + addr + "]";
}
}
**练习2:编写汽车类并画内存图**
属性:颜色,型号,品牌,价格
行为:开,飞。。。
汽车对象的创建和使用
package com.test;
public class Car {
public static void main(String[] args) {
Cars c = new Cars();
c.setBrand("xxx");
c.setColor("yellow");
c.setPrice(133333L);
c.setType("jvnd");
System.out.println(c);
c.drive();
c.fly();
}
}
class Cars{
private String color;
private String type;
private String brand;
private long price;
public void setColor(String color){
this.color = color;
}
public String getColor(){
return color;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
public void setPrice(long l) {
this.price = price;
}
public long getPrice() {
return price;
}
@Override
public String toString() {
return "Cars [color=" + color + ", type=" + type + ", brand=" + brand + ", price=" + price + "]";
}
public void drive() {
System.out.println("kai");
}
public void fly() {
System.out.println("fei");
}
}
创建对象的流程
Person p = new Person();
1.把Person.class文件加载进内存
2.在栈内存中,开辟空间,存放变量
3.在堆内存中,开辟空间,存放Person对象
4.对成员变量进行默认的初始化
5.对成员变量进行显示初始化
6.执行构造方法(如果有构造代码块,就先执行构造代码块再执行构造方法)
7.堆内存完成
8.把堆内存的地址值赋给变量p,p就是一个引用变量,引用了Person对象的地址值
匿名对象
没有名字的对象,是对象的简化表示形式。
使用场景:当被调用的对象只调用一次时。(若被调用的对象需被调用多次时,不宜使用匿名对象,因为多次创建多个对象会占用内存)
Demo d = new Demo();
d.sleep();
d.game();
new Demo().show();//此为匿名对象
new Demo().game();
构造方法
构造方法是一种特殊的方法,它是一个与类同名且返回值类型与同名类型的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的创建或者对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也可以重载。
public class Test{
String name;
public Test2(){}//无参构造
public Test2(String n){//含参构造
name = n;
}
void eat(){
System.out.pringln("Test2的eat()")
}
}
class tt{
public static void main(String[] args){
Test2 t = new Test2();
t.eat();
Test2 t2 = new Test2("张三");
System.out.println(t2.name);
}
}
构造代码块赋值
public class Test2{
String name;
int age;
public Test3(String name,int age){//通过含参构造赋值
this.name = name;
this.age = age;
}
}
//通过set方法赋值
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
}
class Test3{
public static void main(String[] args){
//通过无参构造方法赋值
Test3 t = new Test3();
System.out.println(t.name);
System.out.println(t.age);
//通过含参构造方法赋值
Test 3 t2 = new Test3("zhangsan",20);
System.out.println(t2.name);
System.out.println(t2.age);
//通过set()方法赋值
Test2 t3 = new Test3();
t3.setName("rose");
te.setAge(23);
System.out.println(t3.name);
System.out.println(t3.age);
}
}
构造代码块
1.在类的内部,方法外部的代码块
2.通常用于抽取构造方法中的共性代码
3.每次调用构造方法前都会调用构造代码块
4.优先于构造方法加载
class A{
String name;
//构造代码块,存在于类里方法外,优先于构造方法加载
{
name = "jack";
}
public v(){
System.out.println("无参构造方法")
}
public d(int a){
System.out.println("含参构造方法")
}
}
局部代码块
1.在方法里的代码块
2.通常用于控制变量的作用范围,出了括号就失效
3.变量的范围越小越好,成员变量会有线程安全问题
4.执行顺序:构造代码块优先执行,局部代码块按照顺序执行,构造方法按照顺序执行
package com.test;
public class Test_代码块的执行顺序 {
public static void main(String[] args) {
Student s = new Student();
s.f();
}
}
class Student{
{
System.out.println("构造代码块1");
}
void f() {
System.out.println("构造方法");
{
System.out.println("局部代码块1");
}
}
{
System.out.println("构造代码块2");
}
}
this关键字
this代表本类对象的一个引用对象。
构造函数中,this()必须放在第一行
//name=name;
//age=age;
其实是想把Student类的局部变量name的值赋值给成员变量,相当于你想操作是这样的:
//Student.name=name;
但是你不能直接写类名,这时候就用代表本类的对象this来完成。代码变成了:
this.name=name;
当局部变量和成员变量相同时,用于区分。如果附近有同名变量,会遵从变量的就近原则,那么怎么调用成员变量呢?
public class Test{
public static void main(String[] args){
Animal a = new Animal();
a.f2("jack");
System.out.println(a.name);
}
}
class Animal{
String name;
//当局部变量的名与成员变量的值不一样时,直接拿着局部变量的值给成员变量赋值即可
public void f1(String n){
name = n;
}
//当局部变量的值与成员变量的值一样时,使用this调用成员变量
public void f2(String name){
this.name = name;//调用成员变量
}
}
继承
继承是面向对象最显著的一个特性。
继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类/超类/基类。
这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。
提高复用性:只要继承父类,子类就能拥有和父类一样的功能。
继承的特点
1.使用extends关键字
2.相当于子类把父类的功能复制了一份
3.java只支持单继承
4.继承可以传递
5.不能继承父类的私有成员
6.继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能拓展。
7.像是is a 的关系
public class Test{
public static void main(String[] main){
}
}
class Animal{
String name;
String addr;
public void speak(){
System.out.println("Animal.speak()")
}
}
class Dog extends Animal{
super();
}
super关键字
1.通过super关键字可以使用父类的内容
2.super代表父类的一个引用对象
3.如果用,必须出现在调用位置的第一行。
方法的重写
1.继承后,子类就拥有了父类的功能
2.在子类中,可以添加子类特有的功能也可以修改父类的原有功能
3.子类中方法名与父类完全一样(包括方法的返回值,方法名和参数列表完全一致)时,会发生覆盖/复写操作,相当于修改功能。
注意:
1.父类中的私有方法不能被重写
2.子类重写父类方法时,修饰符要大于父类修饰符的权限
继承中的用法
成员变量的使用
局部的,成员的,父类的
public class Test{
public static void main(String[] args){
Zi z = new Zi();
z.show();
}
}
class Fu{
int num = 10;
}
class Zi extends Fu{
int num = 30;
public void show(){
int num = 9;
System.out.println(num);//9,变量的就近原则
System.out.println(this.num);//30,调用本类的成员变量
System.out.println(super.num);//10,调用父类的成员变量
}
}
成员方法的使用
继承方法,特有方法,重写方法
public class Test2_LeiMethod{
public static void main(String[] args){
Zi2 z = new Zi2();
z.ziEat();
z.ziShow();
}
}
class Fu2{
public void show(){
System.out.println("Fu2...show()");
}
public void eat(){
System.out.println("Fu2...eat()");
}
}
class Zi2 extends Fu2{
//普通方法
public void ziShow(){
super.show();
}
//重写方法
public void ziEat(){
System.out.println("Zi...ziEat()");
}
}
构造方法的使用
1.子类创建对象时,默认会去访问父类的无参构造方法
2.在构造方法的第一行,都有一条默认的语句:super();
3.父类没有无参构造时,可以使用super调用父类的其他构造
public class Test_LeiContruct{
public static void main(String[] args){
Zi3 z = new Zi3();
}
}
class Fu3{
public Fu3(){
System.out.println("Fu3...Fu3()");
}
public Fu3(String name){
System.out.println("Fu..."+name);
}
}
class Zi3 extends Fu3{
public Zi3(){
super();//默认就存在且在第一行
// super("张三");//调用父类中韩餐的构造方法
System.out.println("Zi3...Fu3");
}
public Zi3(String name){
this();//调用本类的无参构造
System.out.println("Zi3..."+name);
}
}
this 和 super的区别
1.this代表本类对象的引用,super代表父类对象的引用。
2.this用于区分局部变量和成员变量
3.super用于区分本类变量和父类变量
4.this.成员变量 this.成员方法() this[参数]代表本类内容
5.super.成员变量 super.成员方法() super([参数]),代表调用父类内容
6、 this和super不可以同时出现在同一个构造方法里,他们两个只要出现都得放在第一行,同时出现的话,到底第一行放谁呢
重写和重载的区别
1.重载:同名不同参。是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同。
2.重写:是存在子父类之间的,子类定义的方法与父类中的方法具有相同的名字,相同的参数表和相同的返回类型。
3.重写是父类与子类之间多态性的一种表现。
4.重载是一类中多态性的一种表现。
static
是java中的关键字,用于修饰成员(成员变量和成员方法)
特点
1.可以修饰成员变量,成员方法
2.随着类的加载而加载,优先于对象加载
3.只加载一次,就会一直存在,不再开辟空间
4.全局唯一,全局共享
5.可以直接被类名调用
6.静态只能调用静态,非静态可以随意调用
7.static不能和this或者super共用,因为有static时可能还没有对象
public class Test{
public static void main(String[] args){
int i = Student.age;
System.out.println(i);
Student s = new Student();
Student s1 = new Student();
//调用方法
System.out.println(s.name);
System.out.println(s.age);
s.speak;
s.eat;
}
}
class Student{
String name = "zhangsan";
static int age = 20;
public void eat(){
System.out.println("eat...");
public static void speak(){
System.out.println("speak...");
}
}
public class Test2{
public static void main(String[] args){
}
}
class Teacher{
static int age = 30;
String name = "王康";
//非静态测试
public void speak(){
System.out.println(age);//非静态可以调用静态
System.out.println(name);//非静态可以调用非静态
qiao();//非静态可以调用静态方法
}
//静态测试
public static void qiao(){
System.out.println(age);//静态能调用静态
// System.out.println(name);//静态不能调用非静态
speak();//静态不能调用非静态方法,只能调用静态方法
}
}
静态代码块
类里方法外。随着类的加载而加载,并且只被加载一次,一般用于项目的初始化。
static{...}
构造代码块
在调用构造方法前会自动调用,每次创建对象都会被调用
局部代码块
方法里的代码块,方法被调用时才会执行
静态--构造代码块--构造方法顺序执行--局部代码块顺序执行
public class Test{
public static void main(String[] args){
Car c = new Car();
c.show();
}
}
class Car{
//构造方法
public void show() {
System.out.println("构造方法1");
{
System.out.println("局部代码块");
}
System.out.println("构造方法2");
}
//静态代码块
static{
System.out.println("静态代码块");
}
//构造代码块
{
System.out.println("构造代码块");
}
}
final
是Java提供的一个关键字,final是最终的意思,final可以修饰类,方法,成员变量。java出现了继承后,子类可以更改父类的功能,当父类功能不许子类改变时可以利用final关键字修饰子类。
特点
1.被final修饰的类,不能被继承
2.被final修饰的方法,不能被重写
3.被final修饰的变量是个常量,值不能被更改
4.常量的定义形式:final 数据类型 常量名 = 值
public class Test1 {
public static void main(String[] args) {
Zi z = new Zi();
z.speak();
z.test();
}
}
//final class Fu{
class Fu{
final String name = "缓缓";
public final void speak() {
System.out.println("Fu...speak()");
}
}
class Zi extends Fu{
//被final修饰的speak方法,不能被重写
public void test(){
//super.name = "大黄";//被final修饰的类,不能被重写。
System.out.println(super.name);
}
}
多态
同一个实体具有多种形式。主要是指同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。好处是可以可以把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码。
特点:
1.多态的前提是继承
2.要有方法的重写
3.父类引用指向子类对象
4.多态中,编译看左边,运行看右边
public class Test2 {
public static void main(String[] args) {
Animal a = new Dog();
a.eat();
}
}
class Animal{
public void eat() {
System.out.println("大小通吃");
}
}
class Dog extends Animal{
public void look() {
System.out.println("狗看家");
}
public void eat() {
System.out.println("吃肉肉");
}
}
多态的好处
1.多态可以让我们不用关心某个对象到底是什么具体类型,就可以使用该对象的某些方法
2.提高了程序的扩展性和可维护性
public class Test{
public static void main(String[] args){
//多态--父类引用指向子类对象
Dog d = new Dog();
Cat c = new Cat();
Animal a = new Dog();
eat(a);
}
public static void eat(Animal a){
a.eat();
}
}
多态的使用
1.成员变量:使用的是父类的
2.成员方法:由于存在重写现象所以使用的是子类的
3.静态成员:随着对象而存在,谁调用的就返回谁的
public class z{
public static void main(String[] args){
//多态的成员变量,就是父类的
Fu f = new Zi();
System.out.println(f.num);
//成员方法
f.study();
f.sleep();
//静态成员
System.out.println(f.count);
}
}
class Fu{
int num = 10;
static int count = 10;
public void study(){
System.out.println("Fu...study()");
}
public static void sleep(){
System.out.println("Fu...sleep()");
}
}
class Zi{
int num = 20;
static int count = 30;
public void study(){
System.out.println("Zi...study()");
}
public static void sleep(){
System.out.println("Zi...sleep()");
}
}
静态变量和实例变量的区别
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
向上转型和向下转型
在JAVA中,继承是一个重要的特征,通过extends关键字,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。
在应用中就存在着两种转型方式,分别是:向上转型和向下转型。
比如:父类Parent,子类Child
向上转型:父类的引用指向子类对象Parent p=new Child();
说明:向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类重写了父类的方法就根据这个引用指向调用子类重写方法。
向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。
Parent p = new Child();//向上转型,此时,p是Parent类型
Child c = (Child)p;//此时,把Parent类型的p转成小类型Child
//其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的
说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。
public static Test{
public static void main(String[] args){
Zi c = new Zi();
c.start();
c.stop();
}
}
class Car{
public void start(){
System.out.println("Car...start");
}
public void stop(){
System.out.println("Car...stop");
}
public void run(){
System.out.println("Car...run");
}
}
class Zi extends Car{
public void start(){
System.out.println("Zi...start");
}
public static void stop(){
System.out.println("Zi...stop");
}
}
异常
用来封装错误信息的对象。
组成结构:类型,提示,行号。
异常的继承结构
Throwable - 顶级父类
-- Error:系统错误,无法修复
-- Exception:可修复的错误
--RunTimeException
--ClassCastException
--[ClassNotFoundException]
异常处理
程序中遇到了异常,通常有两种处理方式:捕获或者向上抛出.
当调用了一个抛出异常的方法时,调用位置可以不做处理继续向上抛出也可以捕获异常.
1.捕获方式:
try{
需要捕获的代码
}catch(异常类型 异常名){
处理方案
}
2.抛出方式:
在会发生异常的方法上添加代码:throws异常类型
public static void main(String[] args) throws Excepion{}
测试
//测试异常的发生和解决
public class Test_Exception{
public static void main(String[] args){
//1.捕获异常:把可能发生的异常的代码放在try里,当异常发生时会被catch住,并执行catch中的代码执行异常处理的代码
try{
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a/b);
}catch(Exception e){
//提出解决方案
System.out.println("您输入的两次整数有误!");
}
}
}
抽象类
java中可以定义没有方法体的方法,该方法由其子类来实现.该没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类.抽象类可以理解为一个只有方法声明没有方法体的特殊类.
修饰符 abstract 返回值 方法名(参数列表);
class A{//一般类
public void eat(){
System.out.println("eat...B")
}
}
abstract class c{//抽象类
public absctract void eat();
}
特点
1.通过java关键字abstract实现
2.可以修饰方法或者类
3.抽象类中没有抽象方法(由子类去实现)
4.如果类中有抽象方法,那该类必须定义为一个抽象类
5.子类继承了抽象类以后,要么还是一个抽象类,要么就是把所有抽象方法都重写.
6.多用于多态中
7.抽象类不可以被实例化
public class Test1_Animal {
public void eat(){
System.out.println("吃饭饭");
}
}
/*
* 每种动物都需要吃,
* 发现了,方法声明都一样,只是方法体不一样
*
class Dog extends Test1_Animal{
public void eat(){
System.out.println("狗吃肉");
}
}
class Cat extends Test1_Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}*/
//上面的eat()声明都一样,就是方法体不一样,那就只抽取方法声明部分。
//The type Animal must be an abstract class to define abstract methods
abstract class Animal extends Object{
//This method requires a body instead of a semicolon
public abstract void eat();
}
//继承抽象类,并实现抽象方法
//The type Dog must implement the inherited abstract method Animal.eat()
abstract class Dog extends Animal{
//可以实现抽象方法,也可以子类再变成一个抽象类
}
class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼");
}
}
构造函数
抽象类也有构造方法,但是不能本身实例化
抽象类的构造函数的用处:一般用于给子类实例化
抽象类的成员变量
既可以有变量,也可以有常量
抽象类的成员方法
抽象类里,既可以有普通方法,也可以有抽象方法
接口
java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以实现多个接口来实现.java接口和java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现.OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,那必须是面向接口的编程,面向抽象的编程,正确地使用接口,抽象类这些.
特点
1.接口中都是抽象方法
2.通过interface关键字创建接口
3.通过interface让子类来实现
4.可以理解成,接口是一个特殊的抽象类
5.接口突破了java的单继承的局限性
6.接口和类之间可以多实现,接口和接口之间可以多继承
7.接口是对外暴露的规则,是一套开发规范
8.接口提高了程序的功能扩展,降低了耦合性.
练习
public class Test{
public static void main(String[] args){
Zi z = new Zi();
}
}
interface fu{
public abstract void study();
public abstract void teach();
}
class Zi implements Fu{
public void study(){
}
public void teach(){
}
}
接口的用法
构造方法
接口里是没有构造方法的.在创建实现类的对象时默认的super(),是调用的默认object的无参构造
成员变量
接口里没有成员变量,都是常量.所以,当定义一个变量没有写修饰符时,默认会加上:public static final
接口的成员方法
接口里的方法,默认都是抽象的,如果不写也是会自动补齐的
总结
1、类和类的关系:继承 extends / 单继承 / 单根继承
-- 继承的意义:为了提高代码的复用性,减少了代码的编写提高开发效率。
-- 方法重写的意义:在不修改父类源码的前提下,在子类中重写业务,从此使用的就是重写后的功能。
-- 要求子类的方法声明和父类一样,只要改方法体。
-- 有了继承有了重写就产生了多态,多态的意义:为了统一程序的调用标准,标准就是父类。
-- 多态 也就是向上转型/向上造型。
-- 向下造型的意义:很少用,相当于想要使用子类的特殊功能,还不如直接创建子类对象简单。
-- class A extends B
-- 其中,A和B都是类,A是子类,B是父类,A就拥有了B的所有功能(除了私有的和构造方法)
-- 其他知识点:this 和super ,构造方法,各种代码块...
2、类和接口关系:实现implements / 单实现 / 多实现
-- class A implements B,C
-- 其中,A是实现类,B和C是接口
-- 要求A 可以把 B 和C 接口里的所有 抽象方法 都重写掉,否则 A 就是抽象类
-- 接口不能创建对象
-- 接口里没有构造方法,接口里都是常量,接口里都是抽象方法
3、接口和接口关系:继承extends / 单继承 / 多继承
-- 接口的多继承的关系,打破了java单继承的局限性
-- interface A extends B,C
-- 其中,A B C 都是接口,A是子接口,同时拥有B和C接口里的所有功能
-- class AImpl implements A
-- 要求AImpl需要重写A接口里的所有方法(是包含B和C接口的所有方法),否则就是抽象类
4、接口和抽象类的区别!!!
-- 不同点:
-- 1、抽象类用abstract关键字描述,接口用interface
-- 2、子类和抽象类之间是extends关系,实现类和接口之间是implements关系
-- 3、抽象类中 可以 有构造方法 ,接口里 不能 出现 构造方法
-- 4、抽象类里可以有 变量,接口里没有变量全都是静态的常量
-- 5、接口里定义常量的语法:public static final String NAME="jack",会为变量自动拼接public static final
-- 6、抽象类里 可以有普通方法 也可以有 抽象方法,接口都是抽象方法
-- 7、抽象类和子类之间是继承关系,而且java中,只支持单继承
-- 8、接口突破了java单继承的局限性,因为接口可以多继承也可以多实现,甚至可以继承的同时多实现
-- 9、接口的复杂用法
-- 多继承: interface A extends B,C 其中A是子接口,同时拥有自己的和BC的功能
-- 多实现: class AImpl implements M,N,O,P 其中AImpl是实现类,需要同时重写MNOP的所有抽象方法,否则就是一个抽象类
-- 继承的同时多实现: class AImpl extends Object implements M,N 一定是先继承后实现
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。