面向对象的基础要点

1.抽象类
2.接口
3.内部类
4.多态
1.抽象类
1.1抽象方法

定义:java中只有方法声明没有方法实现并且被关键字 abstract 修饰的方法就是抽象方法
作用:提取相同功能不同结果的方法的声明部分,不提供方法实现
注意:只能在抽象类和接口中
package com its.abstract;
public abstract class Tree{
//成员属性
public String name = “张三”;
//构造方法
public Tree(){
}
//普通方法
public void show1(){
}
//静态方法
public static void show2(){
//静态有自己的内存地址,调用方法–类名.方法名
}
//代码块
{}
//最终方法
public final void show3(){
//不能被子类重写,但可以使用
}
//抽象方法先将类也定义成抽象的–声明目的是制定标准
public abstract void show4();
public abstract String show5();
public abstract String show6(int i);
}

package com.its.ex8;
public class ZhangSan extends People{
@Override
public void study() {
System.out.println(“张鑫学习的时候喜欢睡觉”);
}
@Override
public void eat() {
System.out.println(“张鑫吃臭豆腐”);
}
}

public class Example {
public static void main(String[] args) {
ZhangSan san = new ZhangSan();
san.study();
}
}
1.2抽象类
类描绘对象------所有对象均由类创建----非所有类可创建对象→抽象类不能实例化对象
→抽象类必须被继承,才能被使用→设计阶段决定是否使用
特点:
S.09–面向对象3
1、有构造方法-----不能创建对象—抽象类不能实例化 抽象类就是用当做父类用的 [天生就是当爹的]
2、构造方法给子类创建对象的时候调用使用-------super语句使用抽象类中构造方法
3、他的抽象方法必须要求子类重写,而且要重写全部的抽象方法 一个普通类如果是抽象类的子类,那么这个类在继承抽象类之后,必须重写抽象方法
使用场景:父类—抽取一系列类的公共资源(属性、行为)

2.接口
2.1概述
Interface----java一种引用数据类型、抽象类型
不是类,但是没有脱离类的本质,拥有抽象类部分功能(抽象方法)
不能被继承,可被类实现
不能用于实例化对象
没有构造方法
所有方法必须是抽象方法
不能包含成员变量,除了static final变量(接口中只能定义常量)
package com.its.ex10;
//接口默认就是抽象的,所以public abstract interface Plant
//abstract所以不用添加就行
public abstract interface Plant {
//构造器 - 禁止
//普通方法 - 默认禁止
//代码块 - 禁止
//变量:接口中定义的变量默认都会转化为常量
//接口中只能允许出现常量, 及时及书写的是一个变量的格式,那么系统也会当做常量运行处理。
public String AGE = “年龄”;
public static final String NAME = “哈哈”;
//抽象方法 - 允许
public void show();
//核心:接口比抽象类作为公共资源处理的时候更专一。并且使用的是实现而不是继承?
//静态方法 - 1.8允许。
}

package com.its.ex10;
public class Tree implements Plant {
@Override
public void show() {
System.out.println(“展示迷人的舞姿”);
}
public static void main(String[] args) {
Tree tree = new Tree();
tree.show();
//通过接口名.属性 拿到接口中的变量(常量)
System.out.println(Plant.NAME);
}
}
接口的多继承(类与类关系,用extends修饰,将一些公共属性和方法抽离作为一个父类,让其子类继承并公共使用)
1.类和类--------单继承(一个子类只能拥有一个父类)、多重继承(父类可以再有父类)。
一个父类可以拥有多个子类。
2.类和接口------多实现,一个类可以实现多个接口,一个接口可以有多个实现类。
public abstract interface Animal{
public abstract void show();
}

public class Dog implements Animal{
@Override
public void show(){
System.out.println(“x”);
}
}

public class Cat implements Animal{
@Override
public void show(){
System.out.println(“y”);
}
}

public class App{
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
Animal d = new Dog();
Animal c = new Cat();
//一个对象的接收类型可以是自己本身,也可以是自己的父类型,同时也可以是自己的接口
}
}

3.接口和接口-------多继承(不是类,但是是同类,可以有继承体系)。
例:public interface Mx extends Ax,Bx,Cx{}
4.接口特性:
接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(1.8之前只能是 public abstract,其他修饰符都会报错 1.8之后可以是defalut)
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(1.8之前 public,1.8之后多defalut)
能定义变量但是系统会默认转为常量使用。
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
抽象类和接口的区别(面试题):

  1. 抽象类是一个类的增强,除了类本身功能,多一个抽象方法,但是接口中的方法1.8之前都是抽象的。 --方法区别
  2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是常量 public static final(public final) 类型的。 – 变量区别
  3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法)1.8不算,而抽象类是可以有静态代码块和静态方法。
  4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。(单继承多实现)
    注:JDK 1.8 以后,接口里可以有静态方法和方法体了。
    注:JDK 1.8 以后,接口允许包含具体实现的方法,该方法称为"默认方法",默认方法使用 default 关键字修饰。更多内容可参考 Java 8 默认方法。
    注:JDK 1.9 以后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。更多内容可参考 Java 9 私有接口方法。
    //java8的非抽象方法 default这的不是访问修饰符,是接口中普通方法的定义规则19public default void show2(){
    //非抽象方法中可以自由定义内容。System.out.println("======================");
    }
    //Java8开始支持静态方法
    public static void show11(){}
    抽象类和接口的区别(标准版)
    1.8之前
    1. 抽象类是类,用abstract修饰,是一种类的增强,除本身类的功能,还支持抽象方法。
    接口不是类,但是没有脱离类的本质,接口中只能定义常量和抽象方法。 – 类的本质
    1. 抽象类的时候时机一般是在程序设计阶段使用,抽离公共部分做父类(父子继承关系),
      接口的时候很广泛,它任何时候都可以去考虑使用,但是如果和抽象类一起使用的时候
      接口一般都是在开发中或开发后升级时使用,接口的存在关系是(接口与类实现关系,接口与接口是多继承) – 使用时机。

1.8 的变化
3. 支持了一个默认修饰符(不写) 可以修饰属性和方法.
4.支持了静态方法的书写,调用方式 接口名.方法名(同变量<常量>)
5.支持了default修饰的方法,其实就是普通方法,可以被实现类重写。通过实现类可以直接调用使用。

3.内部类
3.1概述
定义在一个类中或一个方法中的另一个类称之为内部类。
出现内部类的原因:
1、进行资源隐藏封装
2、变相地实现多继承【java中类的继承不支持多继承】
解释: A类中有三个内部类B,C,D 此时E类继 承A, 相当于继承A,B,C,D四个
分类:
1、成员内部类 (了解)
定义位置:
定义在类的成员位置【类中方法外,也就是类体中,和方法同级】
特点:实例化内部类必须先实例化外部类。
普通成员内部类
public class Student {
//外部类定义任何内容不受限制!
public class Monitor{
//内部类可以定义非静态的资源不能定义静态资源 (静态的成员调用方式是类名.属性名 而内部类不能直接使用类名.属性名)
访问的规则必须先实例化外部类再实例化内部类,既然已经实例化了,静态就失去意义了。
内部类可以使用外部类的所有资源(包括私有)【亮点】
创建方式一:
Student student = new Student();
Student.Monitor monitor1 = student.new Monitor();
创建方式二:
Student.Monitor monitor = new Student().new Monitor();
public class App {
public static void main(String[] args) {
//实例化外部类不受限制 随意。
//内部类示例化有两种方法
//第一:先实例化外部类再实例化内部类
OutClass out = new OutClass();
OutClass.InnerClass inner = out.new InnerClass();
inner.run();
//第二:直接实例化两个类
OutClass.InnerClass inner2 = new OutClass().new InnerClass(); inner2.run();
}
}

私有成员内部类

外部类是不允许定义成私有的,但是内部类可以。(内部类就是当成特殊方法处理了)

public class Student {
private class Monitor{
}
}
1、外部类定义任何内容不受限制!
2、内部类可以定义非静态的资源不能定义静态资源
3、内部类可以使用外部类的所有资源(包括私有)
创建方式:和普通成员内部类相同,但是因为是私有的,只能在当前类中才可以实例化,但是其他类可以通过外部类进行方法调用。完全走封装的体系,私有化内部类,对外提供公开的方法(把内部类隐藏的更深)
//成员内部类(普通成员内部类、私有成员内部类、静态成员内部类)
public class OutClass {
public String str ;
//无论是什么样的内部类,外部类定义的内容都不受影响。
private int ww = 10086;
//私有成员内部类 - private
private class InnerClass{
//定义规则和普通成员内部类一样。不同对象的实例化
public void run(){
str = “武松醉打蒋门神”;
}
}
//提供一个公开的获取数据的方法
public String getInnerStr(OutClass out){
InnerClass inner = out.new InnerClass();
inner.run();
return str;
}
}
package com.its.ex9;
import com.its.ex8.Student;
public class App {
public static void main(String[] args) {
//此时其他类就不允许直接实例化私有成员内部类,目的将信息隐藏的更彻底。
//如果其他类想获取一个内部类的内容。可以都过提供对外的公开方法获取。 OutClass out = new OutClass();
String str = out.getInnerStr(out); System.out.println(str);38 }39}
静态成员内部类
public class Student {
public static class Monitor{
1、外部类定义任何内容不受限制!
2、内部类可以定义任意内容不受限制!
3、静态内部类不能使用外部类的非静态资源,但是可以直接使用静态资源
创建方式:Student.Monitor monitor = new Student.Monitor();
代码示例:

//成员内部类(普通成员内部类、私有成员内部类、静态成员内部类)
public class OutClass {

public  String str ;
//无论是什么样的内部类,外部类定义的内容都不受影响。
private int ww = 10086;

//静态成员内部类
public static class InnerClass{
//定义规则和外部类一样可以书写任何内容,注意因为静态内部类所有不能引用外部非静态内容。
    public void run(){
        System.out.println("我是静态的");
    }
}

}

package com.its.ex9;

import com.its.ex8.Student;

public class App {
public static void main(String[] args) {

    //因为内部类是静态的,所以初始化的时候有点不一样
    OutClass.InnerClass inner = new OutClass.InnerClass();
    inner.run();
}

}

局部内部类
定义在方法的方法体中的内部类就是局部内部类
位置:方法体中
格式
修饰符 返回值类型 方法名(参数列表) {
class 局部内部类名{ }
}
匿名内部类 (重点掌握)
没有名字的内部类就是匿名内部类;
因为没有名字就不能使用正常的类定义方式进行定义,所以匿名内部类有自己独有的定义方式。
匿名内部类的使用前提:必须要有继承关系(抽象父类)或接口实现关系(重点中的重点)
场景:
匿名内部类其实是在继承或者接口关系中,出现的匿名子类或者匿名实现类
继承关系下,匿名内部内的本质就是一个父类的子类对象(匿名内部类就是一个子类的对象). 可以把匿名内部类想象为,为一个父类快速提供一个子类对象便捷方式. 现有一个父类,想要使用它的子类对象做事情,但是没有定义子类直接创建子类的对象,这个时候需要匿名内部类 (创建一个父类对象,但是因为父类需要一个子类的实现,而我们又没有提供,那么默认会生成一个子类对象,这个对象就是匿名对象)
匿名内部类的格式:new 父类类名(参数){
重写父类中方法
}
或new 接口名(参数){
重写接口的抽象方法
}
public abstract class Animal {
//抽象的类是不能new的。
public abstract void eat();
}

package com.its.noname;

public class AnimalExample {
public static void main(String[] args) {
//这里就有提供子类去继承父类。子类中也实现父类的抽象方法 ,所以cat可以直接new
Cat cat = new Cat();

    //如果直接new抽象类,只有提供了实现的抽象方法才允许使用这个抽象类,我们没有提供,那么会默认提供
    Animal animal = new Animal() {
        //重写只发生在接口实现类要么继承体系下,如果匿名内部类继承了Animal
        @Override
        public void eat() {
            System.out.println("金毛喜欢吃.....");
        }
    };
    //原因有人(内部类)提供了抽象方法的实现,如果这里能直接调用
    animal.eat();
}

}

public abstract class Tree {

public abstract void run();

}

package com.its.ex12;

public class App {
public static void main(String[] args) {

    //匿名内部类
    Tree tree1 = new Tree() { //new Tree不是真的new抽象类,是相同与new了当前
        @Override
        public void run() {
            System.out.println("==============");
        }
    };

    tree1.run();

}

}

匿名内部类的本质: 是一个子类或实现类的对象

匿名内部类作为对象直接使用:

1、直接当做匿名对象调用资源使用【只能使用一次】
new 父类类名(参数){
重写父类中相关功能
}.方法名();

2、可以赋值给父类类型的变量
父类类型 对象名 = new 父类类名(参数){
重写父类中相关功能
};
对象名.方法名();

匿名内部类在开发中的使用:
当发现某个方法需要类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统的代码

public class BirdExample {
public static void main(String[] args) {

    //直接当做匿名对象调用资源使用,只能使用一次
    //bird就是一个匿名对象
    new Bird() {
        //匿名内部类
        @Override
        public void eat() {
            System.out.println("鸟爱吃虫.....");
        }
    }.eat();

    //可以赋值给父类类型的变量
    Bird bird = new Bird() {
        @Override
        public void eat() {
            System.out.println("鸟爱吃粮食.....");
        }
    };
    bird.eat();
}

}

public interface Tree {
public void run();
}
package com.its.ex13;

public class App {
public static void main(String[] args) {
new Tree() {
@Override
public void run() {
//这个匿名类就是当前tree的实现类
System.out.println("----------------");
}
}.run();

    //tree.run();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值