JAVA快速学习(二)
类与对象
因为本质是写python的所以类与对象的概念就不赘述了,先看java中类与对象的创建方式
public class Main {public static void main(String[] args) {Cat cat = new Cat();
// Cat cat = new Cat("zh",18); 这样直接不对,这样传参就需要写构造函数cat.name = "zh";cat.age = 18;System.out.println("name"+cat.name);System.out.println("age"+cat.age);}
}class Cat{String name;int age;
}
这里首先低一点就是跟python不一样的,一个类定义好以后不能直接在类加括号传参创建,必须这样复制,而且类型必须一致否则会报错,如果想要加括号就要有构造函数
构造函数
public class Main {public static void main(String[] args) {// 此时可以正常传参,因为Cat类有了对应的构造方法Cat cat1 = new Cat("小白", 3);// 使用一个参数的构造方法(age会自动设为18)Cat cat2 = new Cat("小黑");System.out.println(cat1.name);System.out.println(cat1.age);System.out.println(cat2.name);System.out.println(cat2.age);
// 小白 3 小黑 18}
}class Cat {// 定义成员变量(无需用this循环赋值)String name;int age;// 定义带参构造方法,接收name和age并赋值public Cat(String name, int age) {this.name = name; // this.name指当前对象的name,=号后是传入的参数this.age = age;}public Cat(String name){this.name = name;this.age=18;}
}
JAVA中不像python可以直接给类的属性添加默认值,在python中可以传参使用参数的值,没传直接使用默认值,当然在__init__方法中,JAVA则是需要有构造函数,其实可以理解为python的__init__,不过JAVA特殊的是有多个构造函数,在构造函数中可以给默认值,在类加括号参数的个数来判断执行哪个构造函数
方式对象的属性也是对象.属性名这个没有任何的区别
访问修饰符
public(公共的)
- 作用:被
public
修饰的属性可以在任何地方被访问(同一类、同一包、不同包的类中均可)。 - 示例:
java
运行
public class Cat {public String name; // 任何类都能访问此属性 }
- 作用:被
private(私有的)
- 作用:被
private
修饰的属性只能在当前类内部访问,其他类(包括子类)都无法直接访问。 - 用途:通常用于封装类的内部状态,通过
getter/setter
方法间接访问,保证数据安全性。 - 示例:
java
运行
public class Cat {private int age; // 仅Cat类内部可直接访问// 提供外部访问的方法public int getAge() { return age; }public void setAge(int age) { this.age = age; } }
- 作用:被
protected(受保护的)
- 作用:被
protected
修饰的属性可以在当前类、同一包的其他类、不同包的子类中访问。 - 用途:用于允许子类访问父类的某些属性,兼顾封装性和继承需求。
- 示例:
java
运行
public class Animal {protected String type; // 子类和同包类可访问 }// 不同包的子类 public class Cat extends Animal {public void printType() {System.out.println(type); // 合法,子类可访问父类的protected属性} }
- 作用:被
默认(不写修饰符,也称包访问权限)
- 作用:没有显式修饰符的属性,只能在当前类和同一包的其他类中访问,不同包的类(包括子类)无法访问。
- 示例:
java
运行
class Cat {String color; // 仅同包类可访问 }
访问范围对比表:
修饰符 | 同一类中 | 同一包中 | 不同包的子类 | 不同包的非子类 |
---|---|---|---|---|
public | ✔️ | ✔️ | ✔️ | ✔️ |
protected | ✔️ | ✔️ | ✔️ | ❌ |
默认 | ✔️ | ✔️ | ❌ | ❌ |
private | ✔️ | ❌ | ❌ | ❌ |
在 Java 中,“同包类” 指的是位于同一个包(package)中的类。
包(package)是 Java 中用于组织类的一种机制,类似于文件夹的作用,目的是避免类名冲突并便于管理代码。当多个类被声明在同一个包下时,它们就互为 “同包类”。
示例说明:
假设项目中有如下结构:
plaintext
com.example.animals // 一个包
├── Cat.java
├── Dog.java
└── Bird.java
Cat.java
、Dog.java
、Bird.java
三个类的开头都有package com.example.animals;
声明,因此它们属于同一个包,互为同包类。
同包类的特性:
默认访问权限的可见性:
被默认修饰符(不写修饰符)修饰的类、属性或方法,只能被同包类访问。例如,在
Cat
类中定义默认权限的属性:java
运行
package com.example.animals;class Cat {String name; // 默认权限(同包可见) }
同包的
Dog
类可以直接访问这个属性:java
运行
package com.example.animals;class Dog {void test() {Cat cat = new Cat();cat.name = "小白"; // 合法,同包类可访问默认权限属性} }
无需导包即可使用:
同包类之间互相引用时,不需要通过import
语句导入,直接使用类名即可。
对象的引用
public class Main {public static void main(String[] args) {// 此时可以正常传参,因为Cat类有了对应的构造方法Cat cat1 = new Cat("小白", 3);Cat cat2 = cat1;System.out.println(cat2.age);cat2.age = 5;System.out.println(cat1.age);}
}class Cat {// 定义成员变量(无需用this循环赋值)String name;int age;// 定义带参构造方法,接收name和age并赋值public Cat(String name, int age) {this.name = name; // this.name指当前对象的name,=号后是传入的参数this.age = age;}public Cat(String name){this.name = name;this.age=18;}
}
我们把cat1赋值给了cat2,那么cat2就引用了cat1的属性,因为对象都是引用的,当我们cat2改变了age以后,cat1也会改变,索引打印是“3- 5 ”
方法快速入门
定义方法
public class Main {public static void main(String[] args) {Cat cat = new Cat();int c = cat.GetNumber(1,2);System.out.println(c);}
}class Cat {String name;int age;public int GetNumber(int a, int b){return a+b;}}
其实定义跟python还是比较类型就是方法名,参数,返回值,但是在java中数据类型一定要定义好,限制比较多,返回值的类型要在函数名之前,形参的类型也要定义好,接收返回值也要一定匹配的数据类型,而且还有其他关键字
如果没有返回值,用void
class Cat {public void Index(){System.out.println("a");}
}
方法关键字
访问修饰符:控制方法的访问权限
public
:公开的,任何类都可访问private
:私有的,仅当前类可访问protected
:受保护的,当前类、同包类及子类可访问- 默认(无修饰符):仅当前类和同包类可访问
static:静态方法
- 属于类本身,而非实例对象
- 可通过
类名.方法名()
直接调用,无需创建对象 - 示例:
public static void test() {}
final:最终方法
- 被修饰的方法不能被子类重写
- 示例:
public final void test() {}
abstract:抽象方法
- 只有方法声明,没有方法实现(无方法体)
- 必须存在于抽象类(
abstract class
)中 - 子类必须重写抽象方法(除非子类也是抽象类)
- 示例:
public abstract void test();
native:本地方法
- 表示方法的实现由非 Java 语言(如 C/C++)编写
- 没有方法体,用于调用底层系统功能
- 示例:
public native void test();
synchronized:同步方法
- 用于多线程环境,保证方法的原子性,防止并发问题
- 示例:
public synchronized void test() {}
return:返回语句
- 用于结束方法执行并返回结果(有返回值的方法)
- 示例:
return a + b;