JavaSe基础:面向对象2
1. static关键字
static关键字可修饰成员变量,方法,块及类。被static关键字修饰的变量与方法的使用方式如下:
- 类名.静态变量名/类名.静态方法名()
- 对象的引用.静态变量名/对象的引用.静态方法名()
被static关键字修饰的内容为静态的内容。值得注意的是,成员是属于对象的,只能跟随对象使用,因为成员在对象的堆内存空间中。而static修饰的静态的内容是属于类的,可以跟随类使用。
注:在静态的内容中可以直接使用静态内容,但是不能直接使用成员内容,需要跟随对象使用成员;在成员内容中可以直接使用静态,也可以直接使用成员。
静态变量是独一份的,不在对象的堆内存中,而是在静态区中,在类第一次加载完成之后就会初始化静态内容。成员需要创建对象才在对象堆内存中存在成员,没有对象就没有成员。静态内容是当前这个类型所有对象共享的。
例:
public class StaticTest {
public static void main(String[] args) {
System.out.println(StaticDemo01.a);
StaticDemo01.run();
}
}
class StaticDemo01{
//定义静态变量
static int a = 10;
//定义静态方法
static void run(){
System.out.println("跑起来了");
}
}
2. block块
面向对象学习阶段block块有以下几种类型:
- {}使用在方法中,语句块中为局部代码块或普通语句块,执行时机是跟随方法的调用
- {}使用在类中方法外部为构造块,执行时机是在创建对象new的时候
- static{}使用在类中方法外为静态块,执行时机是在类第一次加载完成之后初始化执行
注:
- 构造块代码先于构造器代码之前执行
- 当存在多个构造块,从上到下依次执行
- 当存在多个静态块,从上到下依次执行
- 静态块在类第一次加载完成之后执行,并且只执行一次
应用场景:
- 静态块:内容的初始化,根据静态块的特点,类加载后只执行一次,为静态变量内容初始化
- 构造块:为成员变量内容做初始化
- 局部代码块:可以把具有相同作用的代码放在一个{}中,具有语义化的特点,也代表一个作用域
执行顺序:静态块->main方法->构造块->构造器
例:
//找到打印顺序+结果
public class BlockTest02 {
public static int a = 0;
{
a = 10;
System.out.println(" 3、非静态代码块执行a=" + a); //a=10,第3步打印
}
static {
a = 6;
System.out.println(" 1、静态代码块执行a=" + a); //a=6,第1步打印
}
public BlockTest02() {
this(a); //
System.out.println(" 6、"+a); //a=10,第6步打印
System.out.println(" 7、无参构造方法执行a=" + a); //a=10,第7步打印
}
public BlockTest02(int n) {
System.out.println(" 4、"+n); //n=6,第4步打印
System.out.println(" 5、"+a);//a=10,第5步打印
}
public static void main(String[] args) {
System.out.println(" 2、main"); //第2步打印
BlockTest02 tsc = new BlockTest02();
}
}
3. package
包机制是用来管理众多java文件的,位置出现在当前java文件的第一行,导包需要指明java类的位置。
有两种类不需要进行导包:
- 同包下的类
- java.lang包下的内容不需要导包
导包的方式:
- 使用类型的时候指定类型的权限定名:包名.类名(但是只有当前这一次有效)
- import 包名.类名:定义在类的上面,导入一次,当前类中都可以使用
- 模糊匹配:例如使用import 包名.* 可以匹配当前包下所有的类,但这样会降低编译效率
- 静态导入:import static 包名.类名.静态内容
注:包取名时不要与jdk定义相同的名字
例:
package com.xxxx;
import java.util.*;
//导入静态内容
import static java.lang.Math.PI;
//导入静态方法不要添加(),因为方法名()这叫方法的调用,执行方法中的代码
import static java.lang.Math.random;
public class ImportTest {
public static void main(String[] args) {
List ls = new ArrayList();
//静态变量
System.out.println(PI);
//静态方法
System.out.println(random());
}
}
4. 封装
封装的概念是隐藏内部的实现细节,对外提供公共的访问方式。
4.1 private关键字
private关键字定义的成员只能在当前类中使用,外部类无法直接使用。
如果外部类想使用需要配合一套公共的访问方式一起使用,包括:
- 设置器:为私有的属性进行赋值(setter方法)
- 访问器:获取私有属性的值(getter方法)
4.2 javabean
javabean泛指一系列的类模板类,标准的javabean规范如下:
- 类是公共的
- 至少存在一个空构造
- 属性私有化
- 公共的访问方式:setter方法和getter方法
例:
public class Person {
//私有成员变量
private String name;
private int age;
//无参构造器
public Person(){
}
//有参构造器
public Person(String name, int age){
this.name = name;
this.age = age;
}
//setter方法
public void setName(String name){
this.name = name;
}
//setter方法
public void setAge(int age){
this.age = age;
}
//getter方法
public String getName(){
return name;
}
//getter方法
public int getAge(){
return this.age;
}
//定义code()方法
public void code(){
System.out.println(age+"的"+name+"正在敲代码!!");
}
}
public class TestPerson {
public static void main(String[] args) {
Person p = new Person();
p.setName("张三");
p.setAge(18);
System.out.println(p.getName());
System.out.println(p.getAge());
p.code();
}
}
5. 继承
继承的目的是为了提高代码的复用性,有子类和父类组成:
- 子类|派生类:继承父类的类
- 父类|基类|超类:被继承的类
类是抽取对象的共性,而父类是抽取子类的共性定义在父类中。
继承的实现方式:子类 extends 父类
继承的特点:
- 子类一旦继承父类,就有权使用父类中的成员
- 子类中定义子类独有的内容
- extends是父类的延续也是父类的扩展
- 一个父类可以存在多个子类
- java中是单继承机制,一个子类只能存在一个父类,单继承机制的优点就是简单,缺点就是不够灵活,不便于程序的后期维护
- 接口可以多实现
例:
public class TestAnimal {
public static void main(String[] args) {
Dog d = new Dog();
d.run();
d.bark();
Cat c = new Cat();
c.run();
c.miao();
}
}
//定义Animal类
class Animal{
public String name;
public int age;
public String type;
public void run(){
System.out.println("跑了起来!!");
}
}
//定义Dog类继承Animal类
class Dog extends Animal{
public void bark(){
System.out.println("汪汪!!");
}
}
//定义Cat类继承Animal类
class Cat extends Animal{
public void miao(){
System.out.println("喵喵!!");
}
}
6. super关键字
super关键字指代父类对象(子类对象内存中的父类对象),与this关键字指代当前new的对象不同。有以下用法:
- 在子类的构造器首行,调用父类构造器,语法为"super(实参)",如果没有显示调用父类的指定构造器,默认在子类构造器的首行调用父类的空构造,this()与super()在构造器的首行调用其他构造器时候不能同时存在
- 区分子父类中同名成员的问题,默认是就近原则,当想要指代父类的成员时,需要通过父类对象调用父类成员,语法为"super.成员变量名",如果不存在同名问题,使用成员时,如果是父类成员,默认省略super,如果是子类成员,默认省略this
注:当存在子父类继承的情况下,创建子类对象需要先创建父类对象再创建子类对象;this和super都不能使用在静态环境中。
例:
public class SuperDemo01 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.test();
}
}
//定义父类
class Fu{
public String name = "张三";
public int age = 18;
public Fu(){
System.out.println("我是父类空构造");
}
public Fu(int a){
System.out.println("我是父类带参构造"+a);
}
}
//定义子类继承父类
class Zi extends Fu{
public String name = "李四";
//this调用当前类中的其他构造器
public Zi(){
this(1);
System.out.println("我是子类空构造");
}
//子类构造器的首行super()调用父类中指定构造器
public Zi(int i){
super(10);
System.out.println("带参构造器"+i);
}
public void test(){
String name = "hahaha";
System.out.println(name); //就近原则
System.out.println(this.name); //李四 当前类中的成员
System.out.println(super.name); //张三 通过父类对象调用父类成员
System.out.println(age); //相当于省略了super.
}
}
7. final关键字
final关键字可以修饰成员也可以修饰局部。
- 被final修饰的变量为常量
- 被final修饰的方法不能被重写
- 被final修饰的类不能被继承
注:当final中修饰的为引用数据类型的数据时,可以修改对象的内存空间中的成员,但不可以修改对象的地址