一、定义
Java面向对象编程(OOP)是一种编程范式,其旨在通过将程序逻辑封装在对象中来使代码更易于理解和维护。Java是一种面向对象的编程语言,它支持封装、继承和多态等概念。以下是Java面向对象编程的核心概念:
- 对象(Object):对象是具有属性和行为的实体。在Java中,对象是通过类定义的。
- 类(Class):类是对象的蓝图,它定义了对象的属性和行为。通过类定义,可以创建多个具有相同属性和行为的对象。
- 封装(Encapsulation):封装是将对象的属性和行为组合在一起,形成一个独立的单元。这有助于隐藏对象的内部实现细节,并提供了对外部代码的抽象。
- 继承(Inheritance):继承是一种机制,允许开发者通过定义一个新类来从现有类继承属性和行为。这有助于代码重用和减少冗余。
- 多态(Polymorphism):多态是指对象在接收相同的消息时可以表现出不同的行为。这可以通过方法的重载或覆盖来实现。
Java语言是面向对象的语言,因此对象是Java语言的核心,外事万物皆为对象,面向对象有三大基本特征,如上,封装,继承,多态。
1.1 封装
四种访问控制级别
优点
1、保护代码被破坏,提高数据安全性。
2、提高了代码的复用性
3、高内聚和低耦合,增强代码的可维护性
比如说一个类最简单的封装就是把属性隐藏起来,只提供 get和set 方法进行操作:
public class 盐蠢 {
private String chun;
public String bing;
public void setchun(){}
public String getchun(){
return chun;
}
}
再比如把尽可能多的东西藏起来,对外提高简洁的接口、或者把所有属性藏起来
比如洗衣机,对外只有两个接口,其他的外界均不知道
public class 洗衣机 {
private String chun;
private String bing;
其他属性。。。
public void 开关(){}
public void 洗衣模式(){
}
}
1.2 继承
语法,使用 extends 关键字来实现
class A extends B {}
详细的我们在下面类跟接口中讲
1.3 多态
允许不同的对象对同一个消息做出不同的响应。
在继承中,子类可以继承父类的属性和方法,也可以重写父类的方法来实现自己的特定行为。当父类的引用指向子类的对象时,可以通过父类的引用调用子类重写的方法,实现多态。
在接口中,类可以实现接口中定义的方法,这样可以实现不同的类拥有相同的行为,也可以通过接口的引用调用这些方法,实现多态。
public class AnimalSound {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
animal1.say();
animal2.say();
}
}
abstract class Animal {
abstract void say();
}
class Cat extends Animal {
private String small_name = "猫";
@Override
void say() {
System.out.println("喵喵喵");
}
}
class Dog extends Animal {
private String small_name = "狗";
@Override
void say() {
System.out.println("汪汪汪");
}
}
二、类与接口
2.1 类
类是同一类事物的统称,将现实世界的一个事物抽象成对象,类是对象的抽象,而对象是类的具体实例,类包括对象的属性和方法。
public class 盐蠢 {
private String chun;
public String bing;
public void setchun(){}
public String getchun(){
return chun;
}
}
属性和方法
Java类的属性(Properties)是指在类中定义的一些变量,用于描述类或类的对象的某些特征或状态。类的属性可以在类的对象创建时进行初始化或者在运行时动态赋值。
在Java中,类的属性可以通过访问修饰符来控制其可见性,如public、protected、private等。public属性可以被任何其他类访问,protected属性可以被同一包中的类和其他类的子类访问,private属性只能被本类访问。
类的属性可以是基本类型(如int、double、char等)或引用类型(如String、List等)。基本类型的属性可以直接赋值,而引用类型的属性需要通过new关键字来创建对象并进行赋值。
访问类的属性可以使用点操作符(.)访问。例如,如果有一个名为MyClass的类,其中有一个名为name的字符串属性,可以使用以下方式访问该属性:
MyClass obj = new MyClass();
String name = obj.name;
类的属性也可以通过getters和setters方法进行访问和修改。getters方法用于获取属性的值,setters方法用于设置属性的值。getters和setters方法通常以驼峰命名法命名,并且setters方法在方法名前加上set关键字。例如:
public class MyClass {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
方法重载 与 重写
重写父类的方法,方法名字、参数、返回值相同,常见的如overwirte
public class Persion {
public String attrite = "";
public void todo(){
System.out.println("属性是:人性本善");
}
}
public class Student extends Persion{
public void todo() { //重写了父类的方法,方法名和参数相同
System.out.println("todo: 属性是,你他妈变坏了啊");
}
}
同一个类中的相同名字不同参数的方法,调用时根据传递的参数不同来区分是哪个方法
public class Persion {
public String attrite = "";
public void todo(){
System.out.println("属性是:人性本善");
}
public void todo(String name){
System.out.println(name + "所有人 属性是:人性本善");
}
}
重写和重载是Java中的两个重要的概念,它们的主要区别有以下几点:
1、定义不同
重载是指在同一个类中,方法名相同但参数不同的方法,编译器根据参数的数量、类型、顺序来区分不同的重载方法。返回值类型可以相同也可以不同。
重写是指在子类中重新定义父类的方法,方法名、参数列表和返回值类型必须与父类中被重写的方法一致。子类可以根据需要修改方法的具体实现,但外观必须与父类的一致。
2、范围不同
重载是在一个类中定义多个方法,允许方法的参数数量、类型或顺序不同。
重写是在子类中重新定义父类的方法,允许方法的参数数量、类型和返回值类型相同。
3、多态性不同
重载是在编译时多态,即编译器在编译时确定调用哪个方法。
重写是在运行时多态,即运行时确定调用哪个方法,可以根据对象的实际类型来调用方法。
4、参数不同
重载的方法参数可以不同,但重写的方法参数必须相同。
5、访问修饰符不同
重载对访问修饰没有特殊要求,可以是public、protected、private或没有访问修饰符。
重写的要求比较严格,被重写的方法必须为public、protected或default访问修饰符,子类方法的访问修饰符不能比父类方法的访问修饰符严格。
6、返回值不同
重载对返回值类型没有要求,可以相同也可以不同。
重写对返回值类型有要求,必须与父类中被重写的方法的返回值类型相同或是其子类。
构造方法
Java构造方法是一种特殊的方法,主要用来实例化对象和初始化对象。构造方法的主要作用是在对象创建时对对象进行初始化,对对象中的实例进行赋值。构造方法的名字必须与定义它的类名完全相同,没有返回类型,甚至连void也没有。构造方法可以被重载,但不允许被继承。当没有指定构造方法时,系统会自动添加无参构造方法。
public class Persion {
public String attrite = "";
// 无参构造方法
public Persion(){
System.out.println("构造方法");
}
public Persion(String name){
System.out.println("构造方法");
}
public void todo(){
System.out.println("属性是:人性本善");
}
}
匿名内部类
Java匿名内部类是一种没有名字的内部类,它是一种实现某项功能的匿名类。匿名内部类可以用来创建一个接口的实例,而不需要额外的类或命名空间。
匿名内部类是在 Java 中使用的一种创建匿名类的语法结构,通常用于处理需要一个类,但不需要将该类定义为一个单独的类的场景。
匿名内部类可以访问外部类的成员变量和成员方法,并且可以继承一个接口,实现接口中的方法。匿名内部类可以用在许多Java应用中,如事件处理、GUI编程等。
例如,下面的代码展示了一个使用匿名内部类的例子:
Button button = new Button() {
{
addClickListener(new ClickListener() {
public void onClick() {
System.out.println("Button clicked");
}
});
}
};
抽象类
使用关键字 abstract
public abstract class Persion {
public String attrite = "";
public abstract void todo();
public void todo(String name){
System.out.println(name + "所有人 属性是:人性本善");
}
}
Java抽象类是一种不能被实例化的类,它主要用于作为抽象类的祖先,提供一些公共方法和属性。抽象类可以包含抽象方法和非抽象方法,但抽象方法不能被实例化。
Java中的抽象类必须被继承并且可以包含抽象方法。如果一个类继承了一个抽象类,那么该类也必须实现抽象类中的所有抽象方法。如果子类没有实现所有抽象方法,那么子类也必须声明为抽象类。
在Java中,抽象类不能被实例化,但可以被其他类继承并使用。抽象类的主要作用是作为公共属性的集合,为不同对象提供共性,因此抽象类主要用于面向对象编程中的类型隐藏。
2.2 接口
在Java中,接口是一种特殊的抽象类,其中所有方法都是抽象的。接口定义了一组规范,这些规范描述了类应该如何实现某些功能。接口中的方法没有具体的实现,只有方法的签名。
以下是一个简单的Java接口定义示例:
public interface MyInterface {
public void doSomething(); // 抽象方法无实现
public int calculateSum(int a, int b); // 抽象方法无实现
}
接口可以包含多个抽象方法,这些方法在接口中不需要提供任何实现,只有方法签名即可。在定义接口时,需要使用关键字interface。
接口也可以包含默认方法和静态方法,这两种方法提供了实现,但是默认方法有默认的实现,而静态方法没有默认实现。
接口中的所有方法默认都是public和abstract的,因此可以省略这些修饰符。此外,接口中可以定义默认方法和静态方法,这些方法提供了实现。以下是一个示例:
public interface MyInterface {
default void doSomething() {
System.out.println("Doing something...");
}
static int calculateSum(int a, int b) {
return a + b;
}
}
实现接口需要使用关键字implements,类可以实现一个或多个接口。实现接口需要实现其中的所有抽象方法。以下是一个示例:
public class MyClass implements MyInterface {
public void doSomething() {
// 实现MyInterface接口中的doSomething方法
System.out.println("Doing something in MyClass...");
}
public int calculateSum(int a, int b) {
// 实现MyInterface接口中的calculateSum方法
return a + b;
}
}
三、super 关键字
Java中的super关键字用于调用父类的构造方法、实例变量和实例方法。
- 调用父类的构造方法:
子类通过super()调用父类的构造方法,在子类的构造方法中必须第一行使用super()来调用父类的构造方法。
public class Animal {
String name;
public Animal(String name) {
this.name = name;
}
}
public class Dog extends Animal {
String breed;
public Dog(String name, String breed) {
super(name); // 调用父类的构造方法
this.breed = breed;
}
}
- 调用父类的实例变量或实例方法:
子类通过super.来访问父类的实例变量或实例方法。
public class Animal {
String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Dog extends Animal {
String breed;
public Dog(String name, String breed) {
super(name); // 调用父类的构造方法
this.breed = breed;
}
public void printName() {
System.out.println(super.getName()); // 调用父类的实例方法
}
}
四、static 关键字
Java中的static关键字用于定义静态变量、静态方法以及静态块。
静态变量是指类变量,而不是实例变量。它们是与类而不是与对象关联的变量。这意味着所有实例都共享静态变量,并且可以通过类名访问静态变量,而无需创建实例。静态变量在内存中只有一份,因此也称为类变量。
静态方法是指与类关联的方法,而不是与实例关联的方法。静态方法可以通过类名访问,无需创建实例。静态方法使用static关键字声明,它们不能访问非静态变量或非静态方法。
静态块是指与类关联的代码块,在类加载时执行。它们用于执行一些初始化任务,例如初始化静态变量或常量。静态块使用static关键字声明。
以下是一个使用static关键字的例子:
public class MyClass {
static int staticVar = 10; // 静态变量
static {
// 静态块,用于初始化静态变量
staticVar = 20;
System.out.println("静态变量被初始化为:" + staticVar);
}
public static void main(String[] args) {
// 访问静态方法
System.out.println("静态方法被调用");
System.out.println("静态变量的值为:" + staticVar);
}
}
五、this 关键字
在 Java 中,this 关键字代表当前对象的引用。this 关键字可以在方法内部访问当前对象的成员变量和方法,还可以用来区分相同名称的局部变量和成员变量。
下面是一个简单的示例:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name; // 使用 this 关键字引用成员变量
this.age = age; // 使用 this 关键字引用成员变量
}
public void introduce() {
System.out.println("My name is " + this.name + ", and I am " + this.age + " years old."); // 使用 this 关键字引用成员变量
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("Tom", 20);
person.introduce(); // 输出:My name is Tom, and I am 20 years old.
}
}
在这个示例中,我们定义了一个 Person 类,其中包含两个成员变量 name 和 age,以及一个带参数的构造函数和一个小写方法 introduce()。在构造函数中,我们使用了 this 关键字来引用成员变量,而在 introduce() 方法中,我们使用了 this 关键字来引用成员变量并打印出个人信息。在 main() 方法中,我们创建了一个 Person 对象并调用了 introduce() 方法。
需要注意的是,在方法内部,this 关键字也可以用来区分相同名称的局部变量和成员变量。例如:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name; // 使用 this 关键字引用成员变量
this.age = age; // 使用 this 关键字引用成员变量
String name = "Tom"; // 声明一个局部变量 name
this.name = "Tom"; // 使用 this 关键字引用成员变量 name
System.out.println("My name is " + this.name + ", and I am " + this.age + " years old."); // 使用 this 关键字引用成员变量
}
}