java基础-第4章-面向对象(二)

简介: final修饰变量:此变量值不能被改变(常量)。所有final修饰的变量只能赋值一次,值不允许改变。

一、static关键字

静态(static)可以修饰属性和方法。

称为静态属性(类属性)、静态方法(类方法)。

静态成员是全类所有对象共享的成员。

在全类中只有一份,不因创建多个对象而产生多份。

不必创建对象,可直接通过类名访问。

例子:

Person p1 = new Person();
        p1.name = "小明";
        p1.age = 23;
        //p1.city = "广州";
        Person p2 = new Person();
        p2.name = "晓东";
        p2.age = 28;
        //p2.city = "广州";
        //.......
        p1.print();
        p2.print();
//        Person.city = "深圳";//静态属性的访问:类名.属性名
//
//        System.out.println("城市:"+Person.city);
        p1.city = "苏州";
        p1.printCity();
        p1.print();
        p2.print();
        //调用静态的方法:类名.方法名
        Person.printCity();
/**
 * 静态变量,属于类,和对象无关,
 */
public class Person {
    String name;
    int age;
    static String city;//静态的,属于类,对象也可以访问,但是所有的对象共享着一份数据;
    static final double PI = 3.14;//表示静态的常量,运行的过程数据不能改变,同时属于类,可以用类名直接调用
    public void eat(){
        System.out.println("吃东西.....");
    }
    public static void test(){
        System.out.println("test()........");
    }
    /**
     * 静态的方法
     */
    public static void printCity(){
        test();
        //System.out.println("name:"+name);
//        eat();
        System.out.println("城市:"+Person.city);
    }
    public void print(){
        printCity();
        eat();
        System.out.println("name:"+this.name+",age:"+age+",city:"+city);
    }
}

静态属性

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

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

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

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

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


静态方法

形成了静态方法。属于类而不再属于对象了,应该由类来访问,但是对象也可以访问。

普通的方法由对象调用。

静态方法中:只能访问属于类,不能访问属于对象。

A:访问静态属性

B:访问静态方法

C:不能直接访问非静态属性

D:不能直接访问非静态方法

非静态方法中:属于类,属于对象都可以访问

A:访问静态属性

B:访问静态方法

C:访问非静态属性

D:访问非静态方法


public void eat(){
        System.out.println(this.name+",吃东西啦。。。"); //非静态方法,可以访问非静态属性
        System.out.println("城市:"+Person.city); //非静态方法,可以访问静态属性
        this.showInfo(); // 非静态方法,可以调用非静态方法。
        Person.printCity(); //非静态方法,可以调用静态方法。
}
    public static void test1(){ //属于类的
        System.out.println(Person.city); //静态方法中,可以访问静态属性。
        Person.printCity();//静态方法中,可以访问静态方法。
//        System.out.println(name); //静态方法中,不能访问非静态的属性
//        this.showInfo(); //静态方法中,不能调用非静态的方法。
    }

静态代码块

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


String name;
    int age;
    static{
        System.out.println("这是静态代码块。。。。");
    }
    /*
    构造代码块:需要调用构造函数才会执行
     */
    {
        System.out.println("这是构造代码块");
    }
    public Demo2(){
        System.out.println("这是无参的构造函数");
    }
    public Demo2(String name,int age){
    }
    public static void main(String[] args) {
        {
            int k = 10;
            System.out.println(k);
        }
        Demo2 demo2 = new Demo2();
        Demo2 demo2_2=  new Demo2();
        //System.out.println(k);
//
//        int i = 100;
//        if(i>100){
//            System.out.println(i);
//
//            int j = 200;//局部变量,作用域只在代码块里面
//            System.out.println(j);
//        }
        //System.out.println(j);
    }

普通代码块:{}包裹起来一段代码。注意作用域。

构造代码块:写在类里,方法外的代码块,就叫构造代码块。当创建对象的时候,随着构造函数的调用而执行。而且优先于构造函数执行。构造函数被多次调用,那么构造代码块也被多次调用。

静态代码块:用static关键字修饰的代码块。在类第一次使用的时候执行,优先于main的执行。只执行一次。例如连接数据库的驱动等

同步代码块:多线程。

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


二、继承

概念

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

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

意义:

A:避免重复的代码。(从子类的角度)

B:扩展类的功能。(从父类的角度)

继承性:子类,父类。存在继承关系。

子类对象,可以直接访问父类的非私有的属性和方法。(避免重复代码)

子类也可以新增自己的属性和方法。(扩展类的功能)

子类可以重新实现父类已有的方法。(扩展类的功能)


语法

父类:A类
子类:B类
语法结构:
class 父类{
}
class 子类 extends 父类{
}



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


public class Person {
    String name;
    int age;
    public void eat(){
        System.out.println("吃东西。。。。。");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}
* extends关键字:表示两个类是继承关系。
 *
 */
public class Student extends Person{
    String school;
    //@Override可以不加,但是如果加上,子类的重写的方法一定要和父类的那个方法名相同
    public void eat(){
        System.out.println("学生吃东西。。。。。");
    }
    public void study(){
        System.out.println("学习了。。。。。");
    }
}
//父类的创建
        Person p1 = new Person();
        p1.name = "乔布斯";
        p1.age = 55;
        p1.eat();
        p1.sleep();
        //p1.study();父类无法访问子类新增的方法和属性
        Student stu = new Student();
        stu.name = "小学生";
        stu.age = 34;
        stu.eat();
        stu.sleep();
        stu.school = "图灵";
        stu.study();//子类肯定可以访问新增的方法

继承中的构造方法

/**
 * 父类,动物类
 */
public class Animal {
    String name;
    int age;
    public Animal(){
        System.out.println("父类的无参的构造方法。。");
    }
    //有参的构造方法
    public Animal(String name,int age){
        System.out.println("父类的有参的构造方法。。");
        this.name = name;
        this.age = age;
    }
    public void eat(){
        System.out.println("吃东西。。。。。");
    }
}
public class Cat extends Animal {
    String color;
    public Cat(){
    }
    public Cat(String name,int age,String color){
        //System.out.println("子类的有参构造");
        //super();//默认调用,隐含调用父类的无参的构造方法
        super(name,age);
        this();//争宠。。
        this.color = color;
        System.out.println("子类的无参的构造方法。。");
    }
    public void catchMouse(){
        System.out.println("抓老鼠......");
    }
}

super关键字

子类对象的创建过程:

子类的构造方法中,默认先调用父类的无参构造方法。如果没有显示的调用,那么隐含着super()。

super关键字:

可以访问父类的属性

可以访问父类的方法

指代父类的构造方法, 如果有多个,靠参数来区分。要在第一行。

this关键字:

作为本类的对象,

访问本类的属性。如果在继承中,本类没有这个属性,那么再找父类中。

访问本类的方法

可以指代本类的构造方法:this()。要在第一行。

class A{
    int i=100;
    int j = 200;
    public void test(){
        System.out.println("i---->"+this.i);
        System.out.println("j---->"+this.j);
        System.out.println("------------test1-------------");
    }
    public void fun(){
        System.out.println("父类的fun()方法。。。");
    }
}
class B extends A{
    int i = 300;
    public void test2(){
        System.out.println("i------>"+super.i);//子类有的,就访问子类
        System.out.println("j------>"+j);//如果子类没有相应的属性,那么会默认去找父类的属性
        System.out.println("------------test2-----------------");
        this.fun();
    }
//    public void fun(){
//        System.out.println("子类重写了父类的fun()方法。。。");
//
//    }
}

this和super的对比:

4cdbed252f0869894380365127c9596f_9ba80e06ba52dbf57efee097f4d7d2e5.png


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


方法重写[重点]

重写:

关键字:override

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

public class Animal {
    String name;
    int age;
    public void eat(){
        System.out.println("动物吃东西。。。。");
    }
}
public class Fish extends Animal {
    String color;
    @Override
    public void eat() {
        System.out.println("鱼游海底。。。。吃东西。。。");
    }
}
Animal a = new Animal();
a.eat();//父类对象,访问父类方法
Fish fish = new Fish();
fish.eat();//子类对象,访问子类重写后的方法。。。

规则:

A:继承关系中。

B:子类重写的方法的声明,必须和父类一致。

方法的返回值(注意点:子类重写的方法的返回类型可以是父类方法返回类型的子类),参数列表,方法名。

C:子类重写方法的访问权限,不能比父类更加严格。

D:重写的方法,不能抛出比父类更大的异常。

重载:overload

概念:一个方法,因为参数不同,执行的具体的方法也不同。

规则:

A:同一个类中。

B:方法名必须一致。

C:参数列表必须不同:顺序,个数,类型。

06918bef510c1d6737917ca1072f6adb_29a081590853826cc1fbac1cd0a334fc.png


三、访问修饰符

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

在Java中,可以在类、类的属性以及类的方法前面加上一个修饰符(modifier),来对类进行一些访问上的控制。

private:私有的,限制在本类中才能访问。

default:什么都不写,就是default。同类,同包。

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

public:公共的,同类,同包,不同包。

示例:

public class Test {
    private int age;//private 只能在本类中访问
    int i;//default:什么都不写,就是default。同类,同包。
    protected int j;//protected:受保护的,同类,同包,不同包(限于子类访问)
    public void print(){//public:公共的,同类,同包,不同包。
        System.out.println("age:"+age);
    }
}

示例:



/**
 * 同一个包,不同的类
 */
public class Demo6 {
    public static void main(String[] args) {
            Test test = new Test();
            //test.age //无法访问私有属性
            test.i = 100;//default修饰的可以在同一个包中访问
            System.out.println("i的值:"+test.i);
            test.j = 200;//protected修饰的,可以在同一个包中访问
            System.out.println("j的值:"+test.j);
            test.print();//同一个包中,可以访问
    }
}
/**
 * 同一个包中,子类
 */
public class SubTest extends Test {
    public void test(){
        //System.out.println(""+this.age);无法访问私有属性
        System.out.println(""+this.j);//子类可以访问
    }
}

package com.tuling.access.sub;


import com.qf.access.Test;

/**
 * 不同的包,子类
 */
public class SubTest2 extends Test {
    public void subTest(){
        System.out.println(""+this.j);//protected修饰的属性,在不同的包中,子类也可以访问
    }
}

package com.tuling.access.sub;



import com.tuling.access.Test;


/**
 * 不同的包,不同的类
 */
public class Demo {
    public static void main(String[] args) {
        Test test =new Test();
        //test.i = 100;//在不同的包中,default修饰的属性无法访问
        //test.j = 200;//在不同的包中,protected修饰的属性无法访问,
        test.print();//不同的包中,可以访问
    }
}

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

3a289d23779c39c7f8726146d27515b8_d4a9504efcab183f26c6e409057bf740.png

最终结论:

private<default<protected<public


四、final关键字

词意:终结的,最终的,最后的。

final可修饰的内容:

类(最终类)

方法(最终方法)

变量(最终变量)


final修饰类:此类不能被继承。String、Math、System均为final修饰的类,不能被继承。

final修饰方法:此方法不能被覆盖。意为最终方法,不支持子类以覆盖的形式修改。


final修饰变量:此变量值不能被改变(常量)。所有final修饰的变量只能赋值一次,值不允许改变。


final修饰基本类型:值不可变

final修饰引用类型:地址不可变

静态常量不再提供默认值,必须手动赋予初始值。

示例:

package com.tuling.part4;
//public final class Animal {//final修饰的类,是不能被继承的
public class Animal {
//    public final void eat(){//修饰的方法,不能被重写
//        System.out.println("动物吃东西。。。。。。");
//    }
    public  void eat(){
        System.out.println("动物吃东西。。。。。。");
    }
    public int test1(){
        System.out.println("test1........");
        return 0;
    }
}

子类:


package com.tuling.part5;

/**
 *
 *
 * 重写
 */
public class Fish extends Animal {
    @Override
    public void eat() {
        System.out.println("鱼吃什么。。。。。");
    }
    //@Override//加上这个标识,一定是重写:返回值要一样,方法名要一样,参数列表要一样
    public int  test1(int a){
        System.out.println("wowowo");
        return 0;
    }
}
相关文章
|
1月前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
23 2
|
3月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
3月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
35 4
|
3月前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
2月前
|
存储 Java 程序员
Java基础-面向对象
Java基础-面向对象
17 0
|
4月前
|
Java 数据处理 开发者
【Java基础面试十二】、说一说你对面向对象的理解
这篇文章阐述了面向对象是一种以类和对象为基础,通过封装、继承和多态等概念来模拟现实世界中的事物及其相互关系的程序设计方法,它强调以事物为中心进行思考和系统构造,与结构化程序设计相比,更符合人类的自然思维方式。
【Java基础面试十二】、说一说你对面向对象的理解
|
3月前
|
安全 Java Go
面向对象程序设计语言:Java
Java语言语法和C语言和C++语言很接近,很容易学习和使用,Java丢弃了C++中很少使用的、很难理解的、令人迷惑的特性,Java语言不使用指针,而是引用,并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧
62 2
|
4月前
|
Java
【Java基础面试十三】、面向对象的三大特征是什么?
这篇文章介绍了面向对象程序设计的三大基本特征:封装、继承和多态,其中封装隐藏对象实现细节,继承实现软件复用,多态允许子类对象表现出不同的行为特征。
【Java基础面试十三】、面向对象的三大特征是什么?
|
3月前
|
Java 开发者
Java 面向对象
Java 是一种面向对象的编程语言,通过对象与类的概念组织代码和数据。面向对象编程的核心包括类、对象、继承、多态、封装和抽象。类是对象的蓝图,定义了属性和行为;对象则是类的实例。继承允许子类继承父类的属性和方法,增强代码复用性;多态则支持通过相同接口调用不同类型对象的行为,包括方法重载和重写。封装通过公共方法隐藏对象细节,提高安全性;抽象则对对象特征进行提炼,通过抽象类和接口实现。理解这些概念有助于设计高效、可维护的 Java 应用程序。
|
4月前
|
Java 开发者 C++