Java 类、对象
什么是类
类是一种抽象概念,一种模板,可以用来定义一类事物的属性和行为。类是面向对象编程的基础。类可以包含属性和方法,可以被使用来创建新对象,然后这些对象可以拥有自己的属性和行为。
示例:学生的基本特征和行为
public class Student {
// 属性
String name;
int age;
String gender;
// 行为
void study(){
System.out.println("Student " + name + " is studying.");
}
void play(){
System.out.println("Student " + name + " is playing.");
}
}
类定义的语法规则
在 Java 语言的世界里,所有的 Java 程序都必须要以类的形式存在。—— 这也是 Java 核心思想:面向对象编程。
类的定义就是以 class 关键字开头定义一个东西:
class 类名
注:类名使用大驼峰命名法1
什么是对象
类作为一种标准化的规范,定义了一个群体。而群体里面的个体就是对象。
包
包是组织类的方式,它们提供了结构和命名空间,使 Java 类可以在多个不同的应用程序中共享。它们还可以用来帮助组织 Java 类,以便于维护。
怎么使用包
包的定义:
package org.idea.java.demo
把 HelloWorld 程序放在指定包 demo 里面:
package org.idea.java.demo
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world!");
}
}
使用包的案例
使用包可以更加合理的去规范我们不同的类的存放地址:
package cat;
public class Cat {
public static void main(String[] args) {
System.out.println("hello cat");
}
}
编译加入了包的java文件报错了:
这是因为类文件加入了包声明,需要在编译命令加上额外参数:
javac -d . Dog.java
补充笔记2:
- Java 用
package
来解决命名冲突,一个类总是属于某个包,类名(比如:Person
)只是一个简写,真正的完整类名是包名.类名
- 在 Java 虚拟机执行的时候,JVM 只看完整类名,因,只要包名不同,类就不同
- 特别注意:包没有父子关系,比如:
java.util
和java.util.zip
是不同的包,两者没有任何继承关系 - 没有定义包名的 class,它使用的是默认包,非常容易引起名字冲突,因此,不推荐不写包名的做法
- Java 编译器最终编译出的
.class
文件只使用完整类名 - 为了避免名字冲突,我们需要确定唯一的包名。推荐的做法是使用倒置的域名来确保唯一性,比如:
org.apache.commons.log
- 要注意不要和
java.lang
包的类重名,即自己的类不要使用这些名字:String
、System
、Runtime
等 - 要注意也不要和 JDK 常用类重名:
java.util.List
、java.text.Format
、java.math.BigInteger
- 编译 src 目录下的所有 Java 文件:
javac -d ./bin src/**/*.java
类的基本组成
类由以下几部分组成:
- 类名: 类的唯一标识,用于定义对象的类型
- 属性:类的实体拥有的特征
- 方法:类的实体可以执行的操作
- 构造函数:创建类的实例的函数
- 继承:一个类可以从另一个类中继承属性的方法
- 接口:定义类的标准,使不同类之间可以交互
方法
方法是在类中定义的函数,表示类的行为。可以有参数,可以被类的实例对象调用。
public class CounterUtil {
public int getMaxNumber(int a, int b) {
return a > b ? a : b;
}
}
那么如何使用方法?在 Java 中,如果要执行一个函数,那么必须从 main 开始入手:
public class CounterUtil {
public int getMaxNumber(int a, int b) {
return a > b ? a : b;
}
public static void main(String[] args) {
CounterUtil counterUtil = new CounterUtil();
int c = counterUtil.getMaxNumber(1, 2);
System.out.println(c);
}
}
使用某个类里的方法步骤总结:
- 创建该类的具体对象
- 通过这个对象去调用内部的方法,语法:
对象名.方法名
构造函数
构造函数是一种特殊的方法,用于初始化类的实例,在实例被创建的时候自动调用。
构造函数的名称必须与类名一致,不返回值,可以有参数。
public class Person {
private String name;
private int age;
// 构造函数
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
构造函数的语法:
[修饰符] 构造函数名(参数列表){
// 构造函数体
}
main 函数
main 函数是每个 Java 程序的入口,是 Java 程序执行的第一个函数。它由一个具有特定名称(main)的静态方法组成,接受一个可选的 String 数组类型参数,且没有返回值。
Q:什么是静态方法?
public class Test {
public static void main(String[] args) {
// code
}
}
继承
继承是一种面向对象编程(OOP)技术,它允许一个类继承另一个类的属性和方法,不需要写重复代码。
继承可以提高代码的可维护性,因为代码更加松散耦合,使得更改和维护代码变得更加容易。
例如:Animal 类,里面有 eat 和 bark 两个方法。这时可以创建一个 Dog 类继承 Animal 类,这样 Dog 就有了 eat 和 bark 方法,当然也可以重新定义 Dog 类中的 bark 方法:
class Animal {
public void eat() {
System.out.println("Animal is eating");
}
public void bark() {
System.out.println("Animal is barking");
}
}
// 继承用 extends 关键字
class Dog extends Animal {
public void bark() {
System.out.println("Dog is barking");
}
}
// 入口程序
class Test {
public static void main(String[] args) {
Dog d = new Dog()
d.eat(); // "Animal is eating"
d.bark(); // "Dog is barking"
}
}
接口
接口是Java中的一种特殊类型,它定义了一组方法,但没有实现任何一个,它只是用来被实现的。接口实现了多态,可以让类型有不同的行为。
Q:如何理解多态?
示例:
MyInterface
接口定义两个方法,任何实现 MyInterface
接口的类都 必须实现这两个方法:
public interface MyInterface {
public void method1();
public void method2();
}
MyClass
类实现了 MyInterface
接口,并实现了接口中定义的两个方法 method1()
和 method2()
public class MyClass implements MyInterface {
public void method1() {
// 实现代码
}
public void method2() {
// 实现代码
}
}
用 implements
关键字实现了某个接口必须实现接口类中定义的方法,否则编译会报错:
接口的作用?
- 解决多继承问题(具体说下?)
- 更好的代码复用,可以让多个类同时实现一个接口,从而实现功能的重用
- 可以让类之间的耦合度降低,提高类的可复用行,接口是一种抽象层,可以隔离类之间的复杂关系
- 可以提高代码的可读性,接口把实现分离了,只需要关注接口的定义,就可以了解一个类的功能
实现接口和继承父类有什么区别?
- 继承父类是指子类继承父类的属性和方法,父类可以有多个子类,而接口是指一个类实现接口,可以定义一组规范,可以让多个不同的类实现这个接口
- 继承父类只能单继承,而接口可以多实现
- 继承父类可以实现代码的复用,而接口可以实现函数定义的复用,提升了抽象层面的复用