Java面向对象_封装,继承,覆写,多态

面向对象

封装

访问控制符

  • 访问控制符用来控制父类、子类间,不同包中的类间数据和方法的访问权限。包括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继承特点
  1. Java是单继承的,不支持多继承。这样使得Java的继承关系很简单,一个类只能有一个父类,易于管理程序。同时一个类可以实现多个接口,从而克服单继承的缺点。
  2. 继承关系是传递的
  3. private修饰的成员变量或方法是不能被继承的
1.2解决什么问题

提高了代码的效率,避免了代码重写。
在这里插入图片描述

2. 语法格式

[修饰符] class 子类 extends 父类 {
//类体
}

  • 继承目的 : 代码重用

  • 语法

class 子类名 extends 父类名 { }

java 中只支持单继承,并且是链式继承(爹不能再继承儿子)

java中的根类 : Object

如果一个类没有显示继承其他类,那么该类默认继承 java.lang.Object

Super
  • super : 保存了父类型特征,可以理解为是父类的对象引用(错的)
    在这里插入图片描述
  1. 用在子类成员方法,可以区分子类和父类同名的成员变量/成员方法
  2. 用在子类构造方法,同上
  3. 用在子类构造 方法中,用于调用父类构造方法
  • 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 就是子类特有,父类没有
  • 子类和父类拥有相同名字的方法,但是功能不一样,叫覆写/重写/覆盖

覆写 特指成员方法,和其他属性无关

  • 什么时候需要进行覆写?

当父类方法无法满足子类的业务需求时,需要对父类方法进行覆写
前提条件

  1. 必须有继承关系的体系中
  2. 不能比原方法有更低的访问权限 >=
  3. 错误不能越来越多,不能有更宽泛的异常 <=
  4. 方法名,返回值,参数列表 都必须一致

方法名不一致,说明是俩方法
参数列表不一致,是方法重载
返回值表示方法的功能,必须一样,不能更改方法的本质

  • 继承的目的 : 代码重用

  • 继承最重要的功能 : 方法覆写

  • 重写的意义 :
    功能越来越强
    使用范围越来越广
    错误越来越少

  • 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() {
//		
//	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值