Java语法相关知识汇总(二)

 第十章、面向对象

一、总结

变量/属性当赋值一次后,若未重新赋值,其值一直不变

方法每调用一次,就执行一次

变量/属性不存在调用,只有方法才能调用

二、面向过程与面向对象

1、面向过程(蛋炒饭  耦合度高,扩展力低)

主要关注点是:实现的具体过程,因果关系(集成显卡的开发思路)

  • 优点:
    • 对于业务逻辑比较简单的程序,可以达到快速开发,前期投入成本较低
  • 缺点:
    • 采用面向过程的方式开发很难解决非常复杂的业务逻辑,另外面向过程的方式导致软件元素之间的“耦合度”非常高,只要其中一环出现问题,整个系统受到影响,导致最终软件的扩展力差。另外,由于没有“独立体”的概念,所以无法达到组件复用

2、面向对象 object-oriented(盖饭  耦合度低,扩展力高)

面向对象:object-oriented 简称OO

主要关注点是:关注对象(独立体)能完成哪些功能(独立显卡的开发思路)

  • 优点:
    • 耦合度低,扩展力高,更容易解决现实世界当中更复杂的业务逻辑,组件复用性强
  • 缺点:
    • 前期投入成本高,需要进行独立体的抽取,大量的系统分析和设计

耦合度和扩展力的关系:反比关系,耦合度越高,扩展力越低

C语言是纯面向过程的,C++是半面向对象,Java是纯面向对象

        现在出现的一些新的编程语言多数都是面向对象的,人在认识现实世界的时候以面向对象的方式,面向对象更符合人的思维方式

面向对象的三大特征:

  • 封装
  • 继承
  • 多态

所有面向对象的编程语言都有这三大特征

采用面向对象的方式开发一个软件,声明周期当中:整个生命周期贯穿使用OO面向对象方式

  • 面向对象的分析:OOA
  • 面向对象的设计:OOD
  • 面向对象的编程:OOP

3、类和对象的概念

类的定义:

  • 类是现实世界当中不存在的,是一个模板,是一个概念。是人类大脑抽象的结果
  • 类代表一类事物
  • 在现实世界中,对象A和对象B之间具有共同的特征,进行抽象总结出一个模板,称为类

对象的概念

  • 对象是现实世界中实际存在的个体。

软件开发的过程:

  • 程序员位于现实世界与虚拟实践的中间点,通过类和对象将现实世界中的东西在虚拟世界实现
  • 程序员先观察现实世界,从现实世界当中寻找对象
  • 寻找了N多个对象后,发现所有对象都有共同特征
  • 程序员在大脑中形成了一个模板(类)
  • Java程序员可以通过Java代码来表述一个类
  • Java程序中有了类的定义
  • 可以通过类来创建对象
  • 有了对象之后,可以让对象直接协作起来形成一个系统

类--(实例化)--》 对象

对象--(抽象)--》类

对象又被称为实例/instance

  • 类描述的是对象的共同特征
  • 在访问这些特征的时候,必须先创建对象
  • 一个类主要描述的是:状态 + 动作

状态--》一个类的属性

动作--》一个类的方法

类{

        属性;//描述对象的状态信息

        方法://描述对象的动作信息

}

属性和方法具体到某个对象之后,可能最终的结果不一样

对象和对象之间有共同特征,但是具体到对象之后有数据的差异

第十一章、java中常用的修饰符关键字

java程序中,类是基本单位,方法是一般单位,成员变量是最小单位

修饰符以类级别为单位 修饰类中的子单位,子单位中不能有任何修饰符

包级别 >  类级别  >  实例级别 

小级别可以直接访问大级别的,大级别不能直接访问小级别的

        在Java中,有许多修饰符关键字用于限制类、方法、变量等的访问级别和特性。以下是常用的修饰符关键字:

一、default:纯包级私有,条件下等同于实例私有

若是在同一个包内的其他类中访问默认等同于实例私有),在不同包中访问时必须加public

        如果在Java中定义类,变量或方法时不加修饰符,它们将默认为使用Java中的默认访问修饰符。对于类的成员变量和方法,它们的默认访问修饰符是“包级私有”(package-private),也称为“default”修饰符。这意味着它们只能在同一个包内的其他类中访问默认对象私有)。对于局部变量,没有默认修饰符,因为它们只能在定义它们的方法或代码块中使用。建议在定义变量和方法时显式指定访问修饰符,以确保程序的可读性和可维护性。

二、public:表示公开的,可以被任何类访问,主要用于打破包级私有,因为public使用import机制可以导包。

 public关键字用于指定公开的访问级别,表示该类、方法或变量可以被其他任何类访问。

主要用于打破包级私有

public class MyClass {
    public int myVariable;
    public void myMethod() {
        // do something
    }
}

         这里,MyClass类和其中的myVariable变量和myMethod()方法都被指定为public,所以它们可以被其他任何类访问。

        在Java编程语言中,public是一种访问修饰符(Access Modifier),它可以用于类、方法、属性等的声明上。public关键字表示这些成员是公共的,可以被任何类、方法或对象调用和访问。

        具体来说,使用public修饰的类、方法、属性等可以被任何其他类访问和调用,无论这些类是否在同一个包中。

        如果一个类不在同一个包中,那么我们需要通过导入(import)语句来引入该类,才能够使用它。

        使用public关键字修饰的类、方法、属性等可以被其他包中的类访问和调用,但是在使用时,需要确保以下两点:

  1. 在使用public成员的类中,需要通过import语句将所使用的类引入进来;
  2. 在被引入的类中,public成员的访问修饰符不能是protected、private或默认(即没有任何访问修饰符),否则在引入该类的外部无法访问这些成员。

        需要注意的是,如果被引入的类是一个包级私有(默认)类,则在另一个包中无法访问该类。在这种情况下,只能在同一个包中的其他类中访问该类。

        假设我们有两个类:com.example.package1.ClassAcom.example.package2.ClassB,它们分别位于com.example.package1com.example.package2两个不同的包中。

ClassA中有一个公共方法public void methodA(),而ClassB中想要使用这个方法。那么,我们需要在ClassB中通过import语句将ClassA引入进来,例如:

package com.example.package2;

import com.example.package1.ClassA;

public class ClassB {
    public static void main(String[] args) {
        ClassA a = new ClassA();
        a.methodA();
    }
}

        在这个例子中,我们使用import com.example.package1.ClassA语句将ClassA引入进来,并在main方法中创建了一个ClassA对象并调用了其中的methodA方法。由于methodA方法是公共的(public),因此可以在其他包中的类中调用它。 

        而如果没有使用public关键字修饰,则只能在同一个包中的其他类中被访问和调用,无法跨越包边界。如果没有修饰符将默认为default“包级私有”,即使跨包导入也无法访问。因为没有public的话直接导入不了

        总的来说,public关键字是Java中非常重要的关键字之一,它使得程序员可以更加方便地进行类的封装、继承、多态等面向对象编程的特性,也使得Java的代码重用性更加高效。

三、private:类和该类实例共同所有

1、只有private修饰  (偏向实例所有),只能在当前类中访问通过实例或非static方法访问。

        private关键字用于指定类和实例共同所有的访问级别,表示该变量或方法只能在当前类中访问

public class MyClass {
    private int myVariable;
    private void myMethod() {
        // do something
    }
}

         这里,myVariable变量和myMethod()方法都被指定为private,所以只有MyClass类内部可以访问它们。

package com.example.mypackage;

public class Address {
    //成员变量中的实例变量
    //城市
    public String city;

    //街道
    public static String street;

    //邮编
    private String zipcode;

    public void fun(){
        zipcode = "jzq666";
        System.out.println(zipcode);
    }

    public static void main(String[] args) {
        Address a = new Address();
        a.fun(); //jzq666
        a.zipcode = "jzq";
        System.out.println(a.zipcode); //jzq
    }
}

2、private static共同修饰  (偏向类所有)只能在当前类中访问通过类或static方法访问。

只能在当前类中访问通过类或static方法访问。出了类就不能访问了,得通过接口

四、protected:表示受保护的,只能在当前类、同一包中的其他类或该类的子类中访问。

protected关键字用于指定受保护的访问级别,表示该变量或方法只能在当前类、同一包中的其他类或该类的子类中访问

public class MyClass {
    protected int myVariable;
    protected void myMethod() {
        // do something
    }
}

         这里,myVariable变量和myMethod()方法都被指定为protected,所以除了MyClass类内部,同一包中的其他类和MyClass的子类也可以访问它们。

五、static:纯类级私有,表示静态的,用于指定类变量或类方法。

        一般情况下没有static和final为纯实例私有       

        static关键字用于指定类变量或类方法,表示它们属于类而不是属于实例对象,可以在没有创建实例对象的情况下直接使用。

        一般通过类来访问,但是   变量(属性)和方法    可以通过实例来强制访问,其实实例并没用到,相当于还是类来访问

public class MyClass {
    public static int myStaticVariable;
    public static void myStaticMethod() {
        // do something
    }
}

         这里,myStaticVariable变量和myStaticMethod()方法都被指定为static,所以可以通过类名直接访问它们,而不需要创建实例对象。

六、final:表示不可变的,用于指定一个类、方法或变量不可被修改。

final关键字用于指定不可变的特性,可以用于指定一个类、方法或变量不可被修改

1、final是一个关键字,表示最终的,不可变的

2、final修饰的类无法继承

3、final修饰的方法无法覆盖(重写)

4、fina修饰的变量一旦赋值之后,不可重新赋值,即final修饰的变量只能赋一次值

  • final修饰的成员变量
    • 必须要进行初始化赋值,不能使用默认初始化,因为成员会进行初始化赋默认值,final修饰赋值后不可修改,所以需要再初始化赋值
    • final修饰的实例变量,系统不负责赋默认值,要求程序员必须手动赋值
      这个手动赋值,在变量后面赋值可以,在构造方法中赋值也可以。
  • final修饰的局部变量
    • 没有默认初始化,不算赋值,需手动赋值

5、final修饰的引用,一日指向某个对象之后,不能再指向其它对象,那么被指向的对象无法被均圾回收器回收,直到当前方法结束,才会释放内存

        final修饰的引用虽然指向某个对象之后不能指向其它对象,但是所指向的对象内部的内存是可以被修改的。

6、final修饰的实例变量,一般和static联合使用,被称为常量,又称静态常量。

  • 常量的定义语法格式: public static final 数据类型 常量名 = 值;
  • 常量和静态变量都是存储在方法区,都是在类加载时初始化,调用方法也一样,区别在于常量不能变
  • 常量名全部大写,每个单词之间采用下划线衔接
  • 常量一般都是公共的,采用public修饰

7、如果一个final变量既在声明时进行了初始化,又在构造函数中进行了初始化,那么在构造函数中的初始化赋值会覆盖声明时的初始化值。

public class MyClass {
    public final int myFinalVariable = 100;
    public final void myFinalMethod() {
        // do something
    }
}

 这里,myFinalVariable变量和myFinalMethod()方法都被指定为final,所以它们不能被修改。

FinalTest01.java

package com.final关键字.javase;

/**
 * 关于java语言中的final关键字:
 *  1、final是一个关键字,表示最终的,不可变的
 *  2、final修饰的类无法继承
 *  3、final修饰的方法无法覆盖
 *  4、final修饰的变量一旦赋值之后,不可重新赋值
 *
 */
public class FinalTest01 {
    public static void main(String[] args) {
        String s = "123";
        System.out.println(s.length());

        String str = new String("666");
        System.out.println(str);

        String s1 = "abc";
        System.out.println(s1.replaceAll("c","a"));

        System.out.println(s1.trim());

        System.out.println(s1.isEmpty());
        
    }
}

FinalTest02.java

package com.final关键字.javase;

public class FinalTest02 {
    //第一种解决方案
    final int i = 10;

    //第二种解决方案
    final int j;
    public FinalTest02(){
        this.j = 10;
    }

    public static void main(String[] args) {
        final int k;
        k = 10;

    }
}

FinalTest03.java

package com.final关键字.javase;

public class FinalTest03 {
    public static void main(String[] args) {
        User u = new User(100);
        //引用重新赋值
//        u = new User(200);

        System.out.println(u.getId());

        final User u1 = new User(300);
        //final修饰的引用,一旦指向某个对象之后,不能在指向其他对象,那么被指向的对象无法被垃圾回收机制回收
        //u1 = new User(400);
        System.out.println(u1.getId());
        //final修饰的引用虽然指向某个对象之后不能再指向其他对象,但是所指向的对象内部的内存是可以被修改的
        u1.setId(400);
        System.out.println(u1.getId());
    }
}



class User {
    private int id;

    public User() {
    }

    public User(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

FinalTest04.java

package com.final关键字.javase;

public class FinalTest04 {
    public static void main(String[] args) {
        System.out.println(Chinese.COUNTRY);

        System.out.println("圆周率:" + Math.PI);
    }
}

class Math{
    public static final double PI = 3.1415926;
}
class Chinese{
    //需求:每一个中国人的国籍都是中国,而且国籍不会改变

    //常量
    static final String COUNTRY = "中国";

}

 FinalTest01.java

public class FinalTest01 {
	public static void main(String[] args){
		A a = new B();
		if(a instanceof B){
			B b = (B)a;
			b.doSome();
		}
		
		final int i;
		//只能赋一次值
		i = 100;
		
		//i = 200;
		System.out.println(i);
	}
}

class A extends Object{
	
}

class B extends A {
	public void doSome(){
		System.out.println("A 's doSome!");
	}
}

FinalTest02.java

public class FinalTest02{
	public static void main(String[] args){
		//Person p = new Person(30);
		//System.out.println(p.age);
		
		//======================================
		
		final Person p1 = new Person(30);
		//错误: 无法为最终变量p1分配值
		//p1 = new Person(30);
		//错误: 无法为最终变量p1分配值
		//p1 = null;
		System.out.println(p1.age);
		p1.age = 50;
		System.out.println(p1.age);
	} 
}

class Person extends Object{
	int age;
	
	public Person(){
		super();
	}
	
	public Person(int age){
		super();
		this.age = age;
	}
}

FinalTest03.java

public class FinalTest03{
	public static void main(String[] args){
		User u = new User(80);
		//System.out.println(u.age);
		
	}
}

class User extends Object{
	
	
	//成员变量
	//错误: 变量 age 未在默认构造器中初始化
	//final int age;
	
	final int age = 20;
	final double height = 180;
	
	//要在系统赋默认值之前赋值
	final double weight;
	
	public User(double weight){
		//这也算赋值
		this.weight = weight;
	}
		
}

FinalTest04.java

public class FinalTest04{
	public static void main(String[] args){
		Chinese c = new Chinese();
		System.out.println(Chinese.COUNTRY);
	}
	
}

class Chinese extends Object{
	//实例变量
	String idCard;
	//实例变量
	String name;
	
	//静态常量,一般都是公开的,常量名大写,单词间用下划线_ 隔开
	public static final String COUNTRY = "中国";
		
}

七、abstract:表示抽象的,用于指定抽象类和抽象方法。

abstract关键字用于指定抽象类和抽象方法,表示这些类和方法没有具体实现,需要由子类实现

public abstract class MyAbstractClass {
    public abstract void myAbstractMethod();
}

 这里,MyAbstractClass类和myAbstractMethod()方法都被指定为abstract,所以需要由子类实现myAbstractMethod()方法。

八、synchronized:表示同步的,用于保证多线程并发执行时的安全性。

synchronized关键字用于保证多线程并发执行时的安全性,可以用于指定方法或代码块

public class MyClass {
public synchronized void myMethod() {
        // do something
    }
}

         这里,myMethod()方法被指定为synchronized,表示在执行该方法时会对该方法加锁,保证同一时间只有一个线程可以访问该方法

九、volatile:表示易变的,用于指定变量在多线程环境下的可见性和原子性。

volatile关键字用于指定变量在多线程环境下的可见性和原子性

public class MyClass {
    public volatile int myVariable;
}

这里,myVariable变量被指定为volatile,表示该变量在多线程环境下的读写操作是原子的,且在一个线程中修改该变量后,其他线程会立即看到该变量的修改结果。 

十、transient:表示瞬态的,用于指定变量不参与序列化过程。

transient关键字用于指定变量不参与序列化过程

public class MyClass implements Serializable {
    private transient int myTransientVariable;
}

         这里,myTransientVariable变量被指定为transient,表示在将MyClass对象序列化时,该变量不会被序列化。

十一、native:表示本地的,用于指定方法用本地语言实现。

native关键字用于指定方法用本地语言实现

public class MyClass {
    public native void myNativeMethod();
}

         这里,myNativeMethod()方法被指定为native,表示该方法的实现是用本地语言(如C、C++等)实现的。

System.out.println() 输出原理

解释一

解释二

        在Java虚拟机启动时,会执行一些初始化操作,其中包括System类的初始化。在System类初始化期间,会创建一个PrintStream对象,并将它赋值给System.out。这个PrintStream对象代表了标准输出流,并且默认情况下将其输出到控制台上。

   System.out对象的初始化是由System类的静态代码块完成的,这个代码块会在System类被加载时执行。System类的加载通常在Java虚拟机启动时就发生了。当Java虚拟机首次加载System类时,它会执行System类的静态代码块,并将System.out初始化为一个PrintStream对象。

        需要注意的是,虽然System.out的初始化是在Java虚拟机启动时发生的,但如果在程序运行时重新赋值System.out,则可以改变输出流的目标。例如,你可以将System.out重新赋值为一个文件输出流,这样所有的System.out输出都会被写入该文件。

这些修饰符关键字可以单独使用,也可以组合使用。组合使用时,一般的顺序为public、protected、private、static、abstract、final、synchronized、volatile、transient和native。

十二、访问控制权限修饰符

1、访问控制权限修饰符来控制元素的访问范围
2、访问控制权限修饰符包括:

  • public:表示公开的,在任何位置都可以访问
  • protected:本类,同包,子类 可访问
  • 缺省:本类,同包 可访问
  • private:表示私有的,只能在本类中访问

3、访问控制权限修饰符可以修饰类、接口,成员变量、方法

属性:4个都能用

实例 / 静态方法:4个都能用

类:public和默认能用,其他不行

接口:public和默认能用,其他不行


4、当某个数据希望某个子类使用,使用protected进行修饰
5、修饰符的范围:
        private < 缺省 < protected < public

6、类只能采用public和缺省 的修饰符修饰(内部类除外)

Test01.java

package com.访问控制权限修饰符.javase;

public class Test01 {
    public static void main(String[] args) {
        User u = new User();
        
        //protected 和 缺省 修饰符修饰的变量,方法 和类都可以同包中调用
        System.out.println(u.i);
        System.out.println(u.j);
    }
}

User.java

package com.访问控制权限修饰符.javase;

public class User {
    //受保护的
    protected int i = 10;

    //缺省的
    int j = 20;

    //可以修饰方法
    private void m1(){

    }

    void m2(){

    }

    protected void m3(){

    }

    public void m4(){

    }

    public static void sumInt(int num){
        int sum = 0;
        boolean flag = true;

        for (int i = 2 ; i <= num ; i++){
            for(int j = 2 ; j < i ; j++){
                if(i % j == 0){
                    flag = false;
                    break;
                }
                flag = true;
            }
            if(flag){
                sum += i;
            }
        }
        System.out.println(sum);
    }

    public static void main(String[] args) {
        sumInt(100);
    }
}

Driver.java

package com.访问权限控制符001.javase;

import com.访问控制权限修饰符.javase.User;

public class Driver extends User {

    public void m(){
        System.out.println(this.i);

        //j为缺省修饰符,只能在同一个包中调用
        //System.out.println(this.j);
    }

}

UserTest.java

package com.访问权限控制符001.javase;

import com.访问控制权限修饰符.javase.User;

public class UserTest {
    public static void main(String[] args) {
        User u = new User();
        //i 为 protected 修饰,只能在同一个包中 或者 不同包中的该类的子类中调用
        //System.out.println(u.i);
    }
}

第十二章、类

一、概述

java中一切皆对象,一切皆类型,只要是属于该类型的变量(引用),都可以调该类型中所有的属性和方法(包括实例和静态的)

二、类的定义

语法结构

[修饰符列表] class 类名 {  //修饰符列表可选

        属性;

        方法;

}

注意:Java语言中所有的class都属于引用数据类型,class后跟的“类名”为引用数据类型,因为通过class定义的是类,属于引用数据类型。

三、类级别和实例级别访问原则

实例级别   <   类级别

  • 访问方面
    • 小级别可以直接访问大级别的,大级别不能直接访问小级别的
  • 包含方面
    • 小级别中有大级别的信息,大级别中没有小级别的信息
      • 实例级别中有类级别的信息
      • 类级别中没有实例级别的信息

注意:类中的一切属性和方法,在类内类外都可以通过实例对象或this访问和修改

四、实例成员永远在运行时解析,静态成员永远在编译时解析

  • 当操作实例成员时,起决定性作用的是引用中保存的值,是在运行时确定
  • 当操作静态成员时,起决定性作用的是引用的类型,是在编译时确定

五、不支持动态添加属性和方法

        Java 是一种静态类型语言,不像 Python 那样支持在运行时动态添加属性和方法。在 Java 中,类的成员(属性和方法)必须在类定义时进行显式声明,并且在运行时无法添加新的成员。

        在 Java 中,要添加新的属性或方法,您需要在类定义中进行声明,然后在相应的对象上调用它们。例如:

public class MyClass {
    // 属性声明
    private int age;

    // 方法声明
    public void sayHello() {
        System.out.println("Hello, I am a method!");
    }

    // Getter 和 Setter 方法用于访问和修改属性
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

然后在其他类中使用 MyClass 的实例时,可以访问已经声明的属性和方法:

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.sayHello();  // 输出: Hello, I am a method!
        
        obj.setAge(25);
        System.out.println("Age: " + obj.getAge());  // 输出: Age: 25
    }
}

        在 Java 中,要动态地添加属性和方法,您需要重新编译类并重新运行程序。这与 Python 的动态性不同,在 Python 中,您可以在运行时动态地修改类和实例的属性和方法。因此,Java 在这方面相对更为严格。 

六、属性

属性(包括实例和静态)都是是采用一个变量的形式来完成定义的,为成员变量,在类体中定义,没有赋值时采用默认值;

  • 只有变量能保存数据
  • 注意:引用数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值