面向对象【封装 继承 多态 关键字】

面向对象【封装 继承 多态 关键字】

1、封装

1.1、概念

指隐藏对象的属性和实现细节,仅对外提供公共访问的方法。

1.2、优点

  • 方便使用;
  • 提高复用性;
  • 提高安全性;

2、继承

2.1、概念

把很多类的相同特征行为进行抽取,使用一个类描述,让多个类和这个类产生一种关系。这样就可以使多个类省略很多的代码,这个关系就是继承,用extends关键字表示

2.2、体系结构

多个具体的对象,不断地向上抽取共享的内容,最终形成了一个继承体系。

2.3、特点

  • Java中只能单继承(单继承:一个子类只能继承一个父类),不能多继承(不能继承多个父类);
class SubDemo extends Demo{} //ok
class SubDemo extends Demo1,Demo2...//error
  • 但Java可以多重继承(即A继承B,B继承C;C是B的父类,B是A的父类)
class A{}
class B extends A{}
class C extends B{}

定义继承需要注意:不要仅为了获取其他类中某个功能而去继承。

日常开发中小技巧:

多层继承出现的继承体系中,通常看父类中的功能,了解该体系的基本功能,建立子类对象即可使用该体系功能。

多重继承虽然能使子类同时拥有多个父类的特征,但是其缺点也是很显著的,主要有两方面:

  1. 如果在一个子类继承的多个父类中拥有相同名字实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。
  2. 如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。

2.4、优点或好处

  1. 继承的出现提高了代码的复用性;提高软件开发效率。
  2. 继承的出现让类与类之间产生了关系,提供了多态的前提。

2.5、子父类中的成员关系

成员变量:

子类方法中使用一个变量时:

  1. 先在方法的局部变量中找,有则使用;
  2. 若(1)中没有,则在本类的成员变量中找,有则使用;
  3. 若(2)中也没有,则在父类的成员变量中找,有则使用;没有,则报错。
成员方法:

用子类对象使用一个方法时:

先在子类中找,有则使用;

若(1)中没有,则在父类中找,有则使用;没有,则报错。

构造方法:

子类的实例化过程:

子类创建对象时,会先去创建父类的对象(默认是去调用父类的无参构造方法);

子类构造方法中,第一行默认是super() (子类需要继承父类的成员使用)。

当父类没有无参构造方法:

必须使用this或者super调用其他的构造方法。

重写和重载的区别:

重载:在同一个类中,方法名相同,参数列表不同,重载可以改变返回类型。

重写:在不同的类中(子父类),方法声明相同(返回类型,方法名,参数列表均相同)

2.6、this和super的区别

this:代表本类对象的引用

super:代表父类的存储空间

3、多态

3.1、前提

  1. 存在着继承或者实现关系;
  2. 有方法的重写;
  3. 父类(接口)引用指向子类(实现)对象。

3.2、思想

指挥同一批对象做事情。比如:带兵打仗,上课下课。

3.3、优点与弊端

优点:

多态的存在提高了程序的扩展性和后期的可维护性。

弊端:

虽然可以预先使用,但是访问父类中已有的功能,运行的是后期子类的功能内容,不能预先使用子类中定义的特有功能。

3.4、对象调用成员的特点

Fu f = new Zi();

成员变量:

编译看左边,运行看左边。

成员方法:

编译看左边,运行看右边。

静态方法:

编译看左边,运行看左边。

编译时期运行时期
成员变量
成员方法
静态方法

4、关键字

4.1、super关键字

  1. 用于显示的调用父类中的构造函数;
  2. super()意为调用父类中不带参数的构造方法;
  3. super(xxx)意为调用父类中带参数的构造方法;
  4. super必须用在子类构造带的第一行。

4.2、this关键字

代表本类对象的一个引用,谁调用this所在的方法,this就代表谁。

使用场景:
  • 用于区分同名成员变量和局部变量;
  • 在定义函数时,该函数内部要用到调用该函数的对象时,因为此时对象还没建立,所以this代表此对象;
  • 构造函数时调用,这个时候,this(参数)必须作为第一条语句存在。
格式:
this.属性  this() this.方法()

4.3、final关键字

其实可以按照final意思来理解:就是最终,不可变的意思,可以用于修饰方法变量

特点:
  • final修饰的类不能被继承;
  • final修饰的方法不能被重写,父类的private成员方法是不能被子类方法覆盖的,因为private类型的方法默认是final类型;
  • final修饰的变量是常量,只能赋值一次,且定义时候必须有初始值不能变;
  • final修饰的引用类型变量,表示该引用变量的引用不能变,而不是引用所指的对象中的数据还是可以变化的;
  • 内部类只能访问被final修饰的局部变量;
  • final不能用于修饰构造方法。

注意:

当程序中一个数据是固定不变的,这时为了增加阅读性,可以给该数据起个名字。为了保证这个变量的值不被修改,加上final修饰,变量就为阅读性很强的常量。书写规范,被final修饰的常量所有的字母都是大写的。如果由多个单词组成单词间通过 _ 连接。

通常规范中:常量名称所有字母大写,若有多个单词组成,单词间使用下划线连接。
public static final 修饰的常量称为全局常量;
public static final double PI = 3.14159265358979323846;
public static final String APP_SEPARATOR = "/"; 

4.4、static关键字

4.4.1、作用

用来修饰成员变量和成员函数。

4.4.2、静态的特点
  • 随着类的加载而加载;
  • 优先于对象存在;
  • 对所有对象共享;
  • 可以直接被类型调用。
4.4.3、静态的注意事项
  1. 静态方法只能访问静态成员(原因:静态的内容是随着类的加载而加载的,先进内存)

  2. 静态方法中不能使用this,super关键字

  3. main()方法是静态的

    main 方法其实也静态的。因为main是程序的入口,是提供给JVM使用的,当在dos中输入java XXX 时,会启动JVM,同时JVM会加载以XXX为名称的这个class文件进内存。并扫描其中有没有main方法。若有main方法JVM就会去调用这个main方法。JVM调用main方法,是不会创建对象的,没有对象怎么调用方法,这个方法只能被静态修饰。JVM通过类名调用的。

4.4.4、静态变量和成员变量的区别
调用方式不同:

静态变量所属与,也称为类变量

成员变量所属于对象,也称为实例变量(对象变量)。

存储位置不同:

静态变量存储于方法区中的静态区中。

成员变量存储于堆内存中。

(局部变量存在于栈内存中)

生命周期不同:

静态变量随着类的加载而加载,随着类的消失而消失。

成员变量随着对象的创建而在堆内存中出现,随着对象的消失而消失。

与对象的相关性:

静态变量是所有对象共享的数据。

成员变量是每个对象特有的数据。

4.4.5、静态的优势和弊端
优势:

对共享的数据进行单独空间的存储,节省内存;

可直接被类名调用。

弊端:

生命周期过长,随着类的消失而消失。

访问出现权限,即静态虽好但只能访问静态。

4.4.6、静态的应用(什么时候使用静态)

当所有对象共享某个数据的时候,就把这个成员变量定义为静态修饰变量;

当某个方法没有访问该类中非静态成员,就把这个方法定义为静态方法。

4.4.7、静态代码块

静态代码块,其实就在代码块前面加上了静态关键字,这个代码块就称为静态代码块。

优先于主方法执行,优先于构造代码块执行,不管创建多少对象,静态代码块只执行一次,可用于给静态变量赋值; 用来给类进行初始化。

public class Person {
	private String name;
	private int age;
	static{
		System.out.println("静态代码块执行了");
	}
}

静态代码块的应用场景类不需要创建对象,但需要初始化,这时可以将部分代码存储到静态代码块中

普通代码块&构造代码块&局部代码块

普通代码块就是直接定义在方法或语句中定义的代码块。

class Demo{

public static void main(String[] args)
{
	{
     int x = 1;
     System.out.println("普通代码块" + x);
	}
	int x = 99;
	System.out.println("代码块之外" + x);
}
//结果:
//普通代码块1
//代码块之外99

构造代码块:直接写在类中的代码块。优先于构造方法执行,构造代码块用于给所有对象初始化用,每创建一次对象就会执行一次构造代码块。构造函数用于给指定对象初始化。

public class Person {
	private String name;
	private int age;
	static{
		System.out.println("静态代码块执行了");
	}	
	{
		System.out.println("构造代码块执行了");
	}
	Person(){
		System.out.println("Person无参数的构造函数执行");
	}
	Person(int age){
		this.age = age;
		System.out.println("Person(age)参数的构造函数执行");
	}
}
class PersonDemo{
	
	public static void main(String[] args)
	{
		Person p = new Person();
		Person p1 = new Person(23);
	}
}

代码块里变量的作用域:只在自己所在区域(前后的{})内有效;

局部代码块:写在局部范围内的代码块。作用:就可以控制局部变量的生命周期。

class Demo 
{
	public static void main(String[] args) 
	{
		{//局部代码块
			int x = 5;
			System.out.println(" 局部代码块..."+x);
		}
		System.out.println(" over...");
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值