一、封装
将类的某些信息隐藏在类内部,不允许外部程序直接访问(隐藏对象的信息)通过该类提供的方法来实现对隐藏信息的操作和访问(流出访问的接口)
特点:1.只能通过规定的方法访问数据
2.隐藏类的实例细节,方便修改和实现
static关键字
1、类属性(静态属性)
1.类对象共享
2.类加载时产生,销毁时释放。
对象名.静态变量名
类.静态变量名
使用实例化后的对象操作时,会有黄色叹号警报,应直接用 类.静态变量名 调用。
普通代码块
在方法体中直接写 {} 顺序执行,先出现,先执行。
构造代码块
在类中直接写 {} 构造代码块是在类被创建时调用,先于构造方法
静态代码块
在类中直接写 static{} 类加载时调用,优先于构造代码块执行
以上三个,当一个类多次实例化,静态代码块只执行一次,其他两种会执行多次。
顺序:静态代码块→构造代码块→普通代码块
2、类方法(静态方法)
1.静态方法中不能直接访问同一个类中的非静态成员(方法和属性),只能直接调用静态成员
2.静态方法中不能使用this,可以通过实例化调用其他方法
二、继承
一种类与类之间的关系
使用已存在的类的定义作为基础建立新类
新类的定义(子类或言派生类)可以增加新的数据或新的功能,也可以用父类的功能,但不能选
择性地继承父类(基类)
即子类可以访问父类的非私有成员
父类无法访问子类任何成员对象
继承的关系
满足"A is a B"的关系就可以形成继承关系
一个子类只能继承一个父类
继承优先于多态(父类引用优先于接口引用)
特点:1.利用代码复用
2.缩短开发周期
访问修饰符
protected:允许在当前类、同包子类/非子类、跨包子类调用;跨包非子类不允许调用
默认:允许在当前类、同包子类/非子类调用;跨包子类/非子类不允许调用
大小顺序:private→默认→protected→public
方法重载
1、同一个类中
2、方法名相同,参数列表不同(参数顺序、个数、类型)
3、方法返回值、访问修饰符任意
4、与方法的参数名无关
方法重写
1、有继承关系的子类中
2、方法名相同,参数列表相同(参数顺序、个数、类型)
3、访问修饰符,访问范围需要大于等于父类的访问范围
4、与方法的参数名无关
5、父类中的static方法不能被子类重写(如果子类和父类中有同名的static修饰的方法名时,则
不为重写)
子类与父类的加载顺序
父类静态方法→子类静态方法→父类对象构造→子类对象构造
父类构造方法
父类的构造不允许被继承、不允许被重写,但是会影响子类对象的实例化
子类构造方法
子类构造默认调用父类无参构造方法
可以通过super()调用父类允许被访问的其他构造方法
super()必须放在子类构造方法有效代码第一行
super
1.子类的构造的过程中必须调用其父类的构造方法
2.如果子类的构造方法中没有显式标注,则系统默认调用父类的无参的构造方法
3.如果子类构造方法中既没有显式标注,且父类中没有无参的构造方法,则编译出错
4.使用super调用父类指定构造方法,必须在子类的构造方法的第一行
代表父类引用:
1.访问父类成员方法super.方法名()
2.访问父类属性super.属性名
3.访问父类构造方法super();
this和super都不能在静态方法中使用
Object类
Object类是所有类的父类
一个类没有使用extends关键字明确标识继承关系,则默认继承Object类(包括数组)
Java中的每个类都可以使用Object中定义的方法
equals比较的是两个引用是否指向同一对象,==比较的是内部的值,当比较的为复合数据类型(类)比较的则是内存地址
equals可以通过重写,改变比较的值
toString
1.输出对象名时,默认会直接调用勒种的toString
2.继承Object中的toString方法时,输出对象的字符串表示形式:类型信息+@+地址信息
3.子类可以通过重写toString方法的形式,改变输出的内容以及表现形式
final关键字
final 类,该类不可被继承
final 方法,该方法不可被重写,但可以被子类继承使用
final 方法内局部变量:只要在具体被使用之前进行赋值即可,一旦赋值不允许被修改
变量成员属性
赋值过程:
1、定义直接初始化
2、构造方法
3、构造代码块
final可配合static使用,类似于常量
使用final修饰可以提高性能,但会降低可扩展性
多态:
概念:允许不同类的对象对同一消息做出不同反应
两种多态:1.编译时多态:设计时多态方法重载
2.运行时多态:程序运行时动态决定调用哪个方法(多数)
必要条件:1.满足继承关系
2.父类引用指向子类对象
向上转型(隐式转型、自动转型)
父类引用指向子类对象可以调用子类重写的方法以及 父类派生的方法,无法调用子类独有方法
注意:父类中的静态方法无法被子类重写,所以向上转型之后,只能调用到父类原有的静态方
法
小类转型为大类例如:父类 对象名=new 子类名();
向下转型(强制类型转换)
子类引用指向父类实例,此处必须进行强制转换,此时就可以调用子类特有的方法
在使用向上转型之后才可以进行向下转型
例如: 父类名 对象名=new 子类名();
子类名 对象名=(子类名)对象名(强转)
或者
子类名 对象名=new 父类名();
https://blog.csdn.net/azhegps/article/details/53608994
instanceof运算符
用于判断该类是否是由该类实例化产生的
极父类、父类、该类返回值都为true
用法:对象名 instanceof 类名
返回值:true/false
抽象类:
abstract 类名(){}
当此类为抽象类时,不可被实例化,只能被继承,可以通过向上转型完成对象实例
子类必须需要重写抽象父类中的方法,否则报错
抽象类里可以没有抽象方法
应用场景:某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法
优点:1.限制了子类的设计随意性
2.阻止了无意义父类的实例化
抽象方法:
abstract 方法名();
不允许包含方法体(不允许具体实现)子类必须重写父类的抽象方法,否则,子类也是抽象类
包含抽象方法的类一定是抽象类
static final private关键字都不可以与abstract并存的
为什么要用抽象类、抽象方法
1、子类的具体方法不需要在父类中实现,只需要在父类中建立一个抽象类,用来提醒程序员
2、需要用抽象方法提醒程序员,必须实现这个方法(子类中重写)(随着每一个子类不同而实现自己的特征)
接口
作用:1、接口定义了某一批类所需要遵守的规范
2、接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只规定这些类里必须提供某些方法
格式:interface 类名()
{public void 方法名();}
接口名 对象名=new 类名();
规则:1、类名以I 打头例如 I类名()
2、接口的访问修饰符为public
3、接口中抽象方法可以不写abstract关键字
4、访问修饰符默认public
5、当一个类实现接口时,此类必须重写接口中的所有方法体,否则需要将该类设置为
抽象类
6、而且以接口名 对象名=new 类名();这种样式的对象名不可以引用类中的方法体
7、接口中可以包含常量,默认为public static final,用接口名.常量名调用或者用实现接
口的类调用 对象名.常量名
8、对象名无法引用类中特有的方法体,
9、我们可以利用接口来描述不同的类型拥有相同的行为特征
default
默认方法,可以带方法体jdk1.8
可以在实现类中重写,并可以通过接口的引用调用
当实现类中实现多个接口,且接口中都有默认方法,必须在实现类中重写接口中的默认方法
static
静态方法,可以带方法体jdk1.8
不可以在实现类中重写,可以用接口名调用
接口名.super.静态方法名()
多接口中重名常量
当一个常量在一个类的父类和其多个接口中都有时,系统无法自行判断子类调用的是哪一个,只有在子类中重写该常量才不报错
接口的继承
接口也可以实现继承关系,并且一个接口可以继承多个父接口
当父接口中有多个重名的方法时,子接口需要重写方法体避免出错
内部类
概念:1.在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类成为内部
类
2.与之对应,包含内部类的类被称为外部类
为什么要使用内部类
通过外部类访问外部类,提供了更好的封装手段
内部类隐藏在外部类之内,更好的实现了信息隐藏
不允许其他的类随意访问
内部类与外嵌类的关系:
1.内部类的外嵌类的成员变量在内部类中仍有效果,内部类中的方法也可以调用外嵌类中的
方法
2.内部类的类体中不可以声明类变量和类方法。外嵌类的累体重可以用内部类声明对象,作
为外嵌类的成员
3.内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象
内部类的分类
成员内部类、静态内部类、方法内部类、匿名内部类
成员内部类
内部类中最常见的就是成员内部类,也成为普通内部类 class 内部类名{}
特点:1.内部类在外部使用时,无法直接实例化,需要借助外部类信息才能完成实例化
方式一:外部类.内部类 对象名=new 外部类().new 内部类()
方式二:外部类对象.new 内部类
方式三:外部类对象.获取方法()
2.内部类的访问修饰符,可以任意,但是访问范围会受到影响
3.内部类可以直接访问外部类的成员;如果出现同名属性,优先访问内部类中定义的
4.可以使用 外部类.this.成员 的方式,访问外部类中同名的信息
5.外部类访问内部类信息,需要通过内部类实例,无法直接访问
6.内部类编译后.class文件命名:外部类$内部类.class
静态内部类
static class 内部类名{}
1.静态内部类对象可以不依赖于外部类对象,直接创建
2.静态内部类中,只能直接访问外部类的静态成员,如果需要调用外部类的非静态成员,
可以通过对象实例
3.获取静态内部类对象实例:外部类.内部类 对象名=new 外部类().new 内部类()
4.可以通过 外部类.内部类.静态成员 的方式,访问内部类中的静态成员
5.当内部类属性与外部类属性同名时,默认直接调用内部类中的成员;如果需要访问外部
类中的静态属性,则可以通过 外部类.属性 的方式;
6.如果需要访问外部类中的非静态属性,则可以通过 new 外部类().属性 的方式;
方法内部类
1.定义在方法内部,作用范围也在方法内
2.和方法内部成员使用规则一样,class前面不可以添加public、private、protected、static
3.类中不能包含静态成员
4.类中可以包含final、abstract修饰的成员
使用时一般将方法设置为Object方法,并return new 内部类名().方法名();
例如:
匿名内部类
类的定义和创建一起完成
适用场景:1、只用到类的一个实例
2、类在定义后马上用到
3、给类命名并不会导致代码更容易被理解
特点:1.匿名内部类没有类型名称、实例对象名称
2.编译后的文件命名:外部类$数字.class
3.无法使用private、public、protected,abstract、static修饰
4.无法编写构造方法,可以添加构造代码块
5.不能出现静态成员
6.匿名内部类可以实现接口也可以继承父类,但不可兼得
图解:
总结:通过向上、向下转型实现对象类型的转换,在转换之前由instanceof判断是否可以转换,提高
代码的强壮型。
当一个类型只限制子类应该有怎样的方法,且不需要准确知道子类如何实现方法时,可以用
abstract定义抽象类。
当多个类型有相同的行为能力,使用接口实现,实现接口的类必须实现接口内的方法体。
内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中其他类的访
问,更好的实现了信息隐藏。