【Java基础】面向对象(二)

本文详细介绍了Java中的static关键字,包括静态属性、静态方法和静态代码块的使用规则。接着讲解了类的继承概念,super关键字的运用以及方法重写。此外,还阐述了访问修饰符的作用和final关键字在类、方法及变量中的应用。内容深入浅出,适合初学者巩固面向对象基础知识。
摘要由CSDN通过智能技术生成

一、static关键字

  • 静态(static)可以修饰属性方法
  • 称为静态属性(类属性)、静态方法(类方法)。
  • 静态成员是全类所有对象共享的成员。
  • 在全类中只有一份,不因创建多个对象而产生多份。
  • 不必创建对象,可直接通过类名访问

示例:

public class Person {

    private String name;
    private int age;
    static String city;//静态属性

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void test() {
        System.out.println("test().......");
    }

    public static void staticMethod() {
    	//静态方法
        System.out.println("city:" + city);
    }
}

静态属性

静态属性,不属于对象
非静态属性(实例属性)属于对象,随着对象的创建而产生,每个对象的属性值都是独立的。

静态属性是属于类的,只有一份(节省内存)。应该由类来访问,但是对象也可以访问,所有的对象共享着一份数据。

非静态属性由对象访问:对象.属性–>赋值,取值
静态属性由类访问:类名.静态属性–>赋值,取值

静态属性可以和final搭配使用,形成静态常量

static final double PI = 3.14;//静态常量

静态方法

静态方法,属于类而不再属于对象了,应该由类来访问,但是对象也可以访问。
普通的方法由对象调用。

静态方法中:只能访问属于类,不能访问属于对象
A:访问静态属性
B:访问静态方法
C:不能直接访问非静态属性
D:不能直接访问非静态方法

非静态方法中:属于类,属于对象都可以访问
A:访问静态属性
B:访问静态方法
C:访问非静态属性
D:访问非静态方法
示例:

public class Person {

    private String name;
    private int age;
    static String city;//静态属性
    static final double PI = 3.14;//静态常量

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void test() {
        System.out.println("test().......");
    }

    public void print() {
        //访问静态属性、非静态属性
        System.out.println("name:" + name + ";" + "age:" + age + ";city:" + city);
        //访问静态方法、非静态方法
        staticDemo();
        test();
    }

    public static void staticDemo() {
        System.out.println("staticDemo()......");
    }

	//静态方法
    public static void staticMethod() {
        //访问静态属性
        System.out.println("city:" + city);

        //访问静态方法
        staticDemo();

		//不能直接访问非静态属性
//        System.out.println("name:"+name);
//        System.out.println("age:"+age);

		//不能直接访问非静态方法 
//        print();
    }
}

静态代码块

代码块,就是一块代码。使用{}包裹起来的。

示例:

public class Demo2 {

    String name;
    int age;

    static {
        System.out.println("这是静态代码块......");
    }

    {
        System.out.println("这是构造代码块......");
    }

    public Demo2() {
        System.out.println("这是无参构造函数......");
    }

    public Demo2(String name, int age) {
        System.out.println("这是有参构造函数......");
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        {
            System.out.println("这是普通代码块......");
            int k = 10;
            System.out.println(k);
        }
        Demo2 demo2 = new Demo2();
    }
}
  • 普通代码块:{}包裹起来一段代码。注意作用域。
  • 构造代码块:写在类里,方法外的代码块,就叫构造代码块。当创建对象的时候,随着构造函数的调用而执行。而且优先于构造函数执行。构造函数被多次调用,那么构造代码块也被多次调用。
  • 静态代码块:用static关键字修饰的代码块。在类第一次使用的时候执行,优先于main的执行。只执行一次。例如连接数据库的驱动等。
  • 同步代码块:多线程。

优先级别:静态代码块 > 构造代码块 >构造方法

二、继承

概念

生活中我们经常听到一些名词,譬如富二代,官二代等,它代表着人与人之间的一种关系。那么程序当中怎么表示这种关系呢?

概念
描述两个类的关系的。在Java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类(派生类,SubClass),现有类被称作父类(超类,SuperClass),子类会自动拥有父类所有非私有的属性和方法

意义:
A:避免重复的代码。(从子类的角度)
B:扩展类的功能。(从父类的角度)

继承性:
子类对象,可以直接访问父类的非私有的属性和方法。(避免重复代码)
子类可以新增自己的属性和方法。(扩展类的功能)
子类可以重新实现父类已有的方法。(扩展类的功能)

语法

语法结构:

class 父类 {

}

class 子类 extends 父类 {

}

extends关键字:表示两个类是继承关系。

示例:

//父类
public class Animal {
    private String type;
    int age;
    String color;

    public Animal() {
        System.out.println("父类Animal无参构造函数......");
    }

    public Animal(String type, int age, String color) {
        System.out.println("父类Animal有参构造函数......");
        this.type = type;
        this.age = age;
        this.color = color;
    }

    public void eat() {
        System.out.println("动物吃东西.....");
    }

    public void print() {
        System.out.println("type:" + type + ";age:" + age + ";color:" + color);
    }
}

//子类
public class Cat extends Animal {
	//新增属性
    String name;

    public Cat() {
        System.out.println("子类Cat无参构造......");
    }

    public Cat(String type, int age, String color, String name) {
        super(type, age, color);//super()指代父类构造函数的时候,也只能放在第一句,如果显式调用了某个构造函数,就不会默认调用无参构造了
        System.out.println("子类Cat有参构造函数......");
        this.name = name;
    }

    //重新实现父类的方法
    @Override//相当于加了约束,
    public void eat(){
        System.out.println("猫吃鱼........");
    }

	//新增方法
    public void catchMouse() {
        System.out.println("抓老鼠......");
    }

}

super关键字

子类对象的创建过程:
子类的构造方法中,默认先调用父类的无参构造方法。如果没有显式的调用,那么隐含着super()。

super关键字:
可以访问父类的属性;
可以访问父类的方法;
指代父类的构造方法, 如果有多个,靠参数来区分。
要在第一行

this关键字:
作为本类的对象,访问本类的属性,如果在继承中,本类没有这个属性,那么再找父类中;
访问本类的方法;
可以指代本类的构造方法:this()。
要在第一行

示例:

//父类
public class A {
    int i;
    int j;

    public A() {
    }

    public A(int i, int j) {
        this.i = i;
        this.j = j;
    }

    public void testA() {
        System.out.println("i:" + i);
        System.out.println("j:" + j);
    }

    public void fun() {
        System.out.println("父类的fun方法....");
    }
}
//子类
public class B extends A {

    int i;//和父类有相同的属性

    public B() {
    }

    public B(int i, int j, int i1) {
        super(i, j);//用super指代父类构造方法
        this.i = i1;//用this访问本类属性
    }

    public void testB() {
        System.out.println("i:" + super.i);//用super访问父类属性
        System.out.println("j:" + j);

        super.fun();//用super访问父类方法
        this.fun();//用this访问本类方法
    }

    public void fun() {
        System.out.println("子类的fun方法....");
    }
}

this和super的对比:

No.比较点thissuper
1访问属性首先在子类中查找,如果没有就在分类中查找直接在父类中查找
2访问方法首先在子类中查找,如果没有就在父类中查找直接访问父类中的方法
3调用构造调用本类中的其它构造方法调用父类的构造方法
4特殊只自身的引用没有概念

this,super关键字不能出现在static方法中

方法重写【重点】

概念:继承关系中,子类将父类已有的方法重新实现,叫做方法重写。

关键字:override

示例:

public class Person {
    String name;

    public void eat() {
        System.out.println("Person类eat()方法.....");
    }


    public Person getType() {
        System.out.println("Person类的getType()方法.....");
        return null;
    }
}
public class Man extends Person {
    //将父类已经有的方法重新实现
    @Override
    public void eat() {
        System.out.println("Man类eat()方法.....");
    }

    @Override//约束我们一定要符合重写的规则
    public Man getType() {
        System.out.println("Man类的getType()方法.....");
        return null;
    }
}

规则:
A:继承关系中。
B:子类重写的方法的声明,必须和父类一致。方法的返回值(注意点:子类重写的方法的返回类型可以是父类方法返回类型的子类),参数列表方法名
C:子类重写方法的访问权限,不能比父类更加严格。
D:重写的方法,不能抛出比父类更大的异常

方法重载:
概念:一个方法,因为参数不同,执行的具体的方法也不同。
关键字:overload
规则:
A:同一个类中。
B:方法名必须一致
C:参数列表必须不同:顺序,个数,类型。

方法重写和方法重载的对比:

No.比较点方法重写方法重载
1单词OverridOverload
2范围继承(子类)同一个类里
3对方法的要求和父类的方法名一致,参数列表一致,返回类型一致方法名一致,参数列表不同,返回值类型无要求
4对访问权限的要求不能比父类的访问权限更加严格对访问权限无要求

三、访问修饰符

访问权限:对方法变量常量等访问位置的限定,通过访问修饰符来实现。

在Java中,可以在类、类的属性以及类的方法前面加上一个修饰符(modifier),来对类进行一些访问上的控制。
private:私有的,限制在本类中才能访问。
default:什么都不写,就是default。同类,同包。
protected:受保护的,同类,同包,不同包(限于子类访问)
public:公共的,同类,同包,不同包。

示例:

package com.idiot.part3;

public class Test {
    private int age;//private 只能在本类中访问

    int i;//default:什么都不写,就是default。同类,同包。

    protected int j;//protected:受保护的,同类,同包,不同包(限于子类访问)

    public void print() {//public:公共的,同类,同包,不同包。
        System.out.println("age:" + age);
    }
}
package com.idiot.part3;

/*
* 同一个包,不同类
*/
public class TestDemo {
    public static void main(String[] args) {
        Test t = new Test();
        //System.out.println("age:" + t.age);private 修饰,同一个包,不同的类,不能访问
        System.out.println("i:" + t.i);//default 修饰,同一个包,不同的类,可以访问
        System.out.println("j:" + t.j);//protected 修饰,同一个包,不同的类,可以访问
        t.print();//public 修饰,同一个包,不同的类,可以访问
    }
}
package com.idiot.part3.other;

import com.idiot.part3.Test;

/*
* 在不同的包,不同的类,是子类
*/
public class SubTest extends Test {
    public void func() {
        System.out.println("j:" + j);//protected:受保护的,同类,同包,不同包(限于子类访问)
    }
}
package com.idiot.part3.other;

import com.idiot.part3.Test;

/*
* 不同的类,不同的包
*/
public class TestDemo2 {
    public static void main(String[] args) {
        Test t = new Test();

        //System.out.println("i:" + t.i);//default 修饰,不同包,不同的类,不能访问
        //System.out.println("j:" + t.j);//protected 修饰,不同包,不同的类,不能访问(限于子类访问)
        t.print();//public 修饰,不同包,不同的类,,可以访问
    }
}

对类的修饰:只能是default和public,protected不能修饰一个类

四个访问修饰符的对比:

修饰符同一个类中同一个包中子类中(不同包)全局
privateYes
*default *YesYes
protectedYesYesYes
publicYesYesYesYes

private < default < protected < public

四、final关键字

词意:终结的,最终的,最后的。
final可修饰的内容:
类(最终类)
方法(最终方法)
变量(最终变量)

final修饰类:此类不能被继承。String、Math、System均为final修饰的类,不能被继承。
final修饰方法:此方法不能被覆盖。意为最终方法,不支持子类以覆盖的形式修改。
final修饰变量:此变量值不能被改变(常量)。所有final修饰的变量只能赋值一次,值不允许改变。

final修饰基本类型:值不可变
final修饰引用类型:地址不可变
静态常量不再提供默认值,必须手动赋予初始值

示例:

public final class Animal {
    private String name;
    //静态的常量
    public static final double PI = 3.14;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public final void eat() {
        System.out.println("动物吃东西......");
    }
}
//public class Dog extends Animal{//final修饰的类不能被继承
//
//    //final修饰的方法不能被重写
//    public void eat(){
//
//    }
//}
public class TestAnimal {

    public static void main(String[] args) {
        final int age = 23;//常量:final修饰基本类型:值不可变
        System.out.println("age:" + age);

//        age = 34;//值不可变
//        System.out.println("age:" + age);

        final Animal a = new Animal();//final修饰引用类型:地址不可变
        a.setName("woowow");
        
        //a = new Animal();//地址不可变

        a.setName("12121212");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值