面向对象
封装
访问控制符
- 访问控制符用来控制父类、子类间,不同包中的类间数据和方法的访问权限。包括private、protected、public和默认四中类型。其访问权限如下:
访问控制符 | 同一类中 | 同一包中 | 同一子类中 | 其他 |
---|---|---|---|---|
private | 是 | 否 | 否 | 否 |
default | 是 | 是 | 否 | 否 |
protected | 是 | 是 | 是 | 否 |
public | 是 | 是 | 是 | 是 |
Private : 除了当前类 , 在哪里都调用不了
Public : 哪都行,都能调用
Protected : 继承权限,同包,同类,子类 可以 其他都不行
默认 : 默认为包权限,同包,同类可以,其他都不行
public class PPP_01 extends B {
public static void main(String[] args) {
A a = new A();
System.out.println(a.a);
// System.out.println(a.b);
System.out.println(a.c);
System.out.println(a.d);
B b = new B();
// System.out.println(b.a);
// System.out.println(b.b);
System.out.println(b.c);
// System.out.println(b.d);
// protected是需要使用子类对象调用
PPP_01 p = new PPP_01();
System.out.println(p.d);
}
}
继承
1.概念
- 继承是从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,并能扩展新的属性和行为。
1.1 Java继承特点
- Java是单继承的,不支持多继承。这样使得Java的继承关系很简单,一个类只能有一个父类,易于管理程序。同时一个类可以实现多个接口,从而克服单继承的缺点。
- 继承关系是传递的
- private修饰的成员变量或方法是不能被继承的
1.2解决什么问题
提高了代码的效率,避免了代码重写。
2. 语法格式
[修饰符] class 子类 extends 父类 {
//类体
}
-
继承目的 : 代码重用
-
语法
class 子类名 extends 父类名 { }
java 中只支持单继承,并且是链式继承(爹不能再继承儿子)
java中的根类 : Object
如果一个类没有显示继承其他类,那么该类默认继承 java.lang.Object
Super
- super : 保存了父类型特征,可以理解为是父类的对象引用(错的)
- 用在子类成员方法,可以区分子类和父类同名的成员变量/成员方法
- 用在子类构造方法,同上
- 用在子类构造 方法中,用于调用父类构造方法
- super(参数);
必须在子类构造方法的第一行
如果 子类构造方法中 没有出现 this(xxx) 和 super(xxx)的话 会默认有一个super() 去调用父类的无参构造
this(xxx) 这种写法必须出现在构造方法第一行,所以 this(xxx) 和 super(xxx) 不能同时出现
this和super都不能出现在静态上下文中
public class Super_01 extends A {
Super_01() {
// 不写,默认会有 super() 调用父类无参构造
super();
System.out.println("子类构造方法!");
}
int i = 2;
public static void main(String[] args) {
// TODO Auto-generated method stub
Super_01 s = new Super_01();
s.m1();
}
public void m1() {
// 子类
System.out.println(i);
// 父类
System.out.println(super.i);
// 父类
System.out.println(this.i);
}
}
class A {
A() {
super();
System.out.println("父类构造方法!");
}
int i = 10;
}
- 如果构造方法私有化,就不能再有其他类继承该类
因为子类想要实例化对象,必须在构造方法中,调用父类的构造方法
如果父类构造方法私有化,那么子类调用不到,报错
public class Super_02 extends B {
public Super_02() {
super();
}
}
class B {
// private B() {
// 构造方法 B 如果用 private 修饰,则类 B 继承会出错
public B() {
}
}
注意 :
-
构造方法可以和静态方法/成员方法重名吗?
-
静态方法/成员方法的方法名可以和类名相同吗?
可以 -
如何区分?
看返回值,构造方法 没有返回值,连void都没有
public class Super_03 {
public static void main(String[] args) {
new Super_03();
}
// 成员方法
public void Super_03() {
System.out.println("11111");
}
// 构造方法
public Super_03() {
System.out.println("123456");
}
}
创建完对象后就立刻执行动态代码段
- 静态代码段 > 非静态代码段 > 构造方法 > 成员方法
实例 :
public class Super_04 {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Sub();
// 父类非静态代码段1
// 子类静态代码段1
// 父类实例代码段1
// 父类构造方法
// 子类实例代码段1
}
}
class Sub extends Sup {
{
System.out.println("子类实例代码段1");
}
static {
System.out.println("子类静态代码段1");
}
Sub() {
// super();
this(2);
}
Sub(int i) {
super();
}
}
class Sup {
static {
System.out.println("父类非静态代码段1");
}
{
System.out.println("父类实例代码段1");
}
Sup() {
super();
System.out.println("父类构造方法");
}
}
Override
- 继承之后 子类必须和父类一模一样吗?
不需要 - 子类有特有的属性,比如 父类只有m1 , 子类中 还有 m2 ,这个m2 就是子类特有,父类没有
- 子类和父类拥有相同名字的方法,但是功能不一样,叫覆写/重写/覆盖
覆写 特指成员方法,和其他属性无关
- 什么时候需要进行覆写?
当父类方法无法满足子类的业务需求时,需要对父类方法进行覆写
前提条件
- 必须有继承关系的体系中
- 不能比原方法有更低的访问权限 >=
- 错误不能越来越多,不能有更宽泛的异常 <=
- 方法名,返回值,参数列表 都必须一致
方法名不一致,说明是俩方法
参数列表不一致,是方法重载
返回值表示方法的功能,必须一样,不能更改方法的本质
-
继承的目的 : 代码重用
-
继承最重要的功能 : 方法覆写
-
重写的意义 :
功能越来越强
使用范围越来越广
错误越来越少 -
Overload和Override的区别?
分别说明是什么
Override 是方法的覆写,必须有继承关系,功能比原方法有更宽泛的异常,不能有更低的访问权限,方法名参数列表
返回值必须一致,覆写特指成员方法 Overload是重载的意思,重载就是方法名相同,参数列表不同,列表不同分为个数不同和类型不同
public class Override_01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat cat = new Cat();
cat.move();
System.out.println(cat.i);
Animal a = new Animal();
a.move();
// 多态
Animal ac = new Cat();
ac.move();
System.out.println(ac.i);
// 猫在走猫步!
// 20
// 动物在移动!
// 猫在走猫步!
// 10
}
}
class Animal {
int i = 10;
public void move() {
System.out.println("动物在移动!");
}
}
class Cat extends Animal {
int i = 20;
public void move() {
// super.move();
System.out.println("猫在走猫步!");
}
}
Final
- final :
类 : 不能被继承
成员方法 : 不能被覆写
修饰的变量 : 不能二次赋值,并且没有默认值,在整个程序的生命周期中,值不能被改变
常量 : 整个程序生命周期中,值不会被更改 / 使用final修饰的变量就是常量, 字面量也是常量
- 分为三种 :
静态常量(fianl修饰的静态变量,一般是public static final ,由于是公共的,和对象没有关系,所以应用较多) ,成员常量 , 局部常量
所以 一般我们把 final修饰的静态变量 叫常量
命名规则 建议 全大写,在eclipse中 使用 蓝色、斜体 、 加粗 显示
final int a;
Final_01(int i) {
a = i;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Final_01 f = new Final_01(2);
// f.i = 3;
// final 修饰的变量不能被更改
System.out.println(123);
}
}
//final class A{
class A {
// final 修饰的方法不能被重写
public final void m1() {
}
}
//final 修饰的类不能被继承
class B extends A {
// public void m1() {
//
// }
}