java学习day-5 面向对象与类

一、什么是面向对象、类
1.什么是对象?

对象是类的实例,具有具体属性和行为,一切客观存在的事物都是对象。

2.什么是类?

类是对大量对象共性的抽象,类是客观事物在人脑中的主观反映,类是对象的模板,定义对象的属性和方法。

例如:动物类有名字和肤色特征,会叫会吃喝,等等。

从而得出,类的组成是属性和行为。

3.类的分类?

(1)普通类(class)

普通类是 Java 中最常见的类类型。它可以有属性(成员变量)和方法,并且可以创建该类的实例(对象)

public class Student {
    //学生类
   
}

作用:普通类用于表示现实世界的实体,并封装数据和行为(通过属性和方法)

  • 可以实例化(即创建对象)

  • 可以有构造器、成员变量、方法

  • 可以继承其他类并实现接口

(2)抽象类(abstract class)

抽象类是一种不能被实例化的类,它通常用于表示通用的概念,具体的实现交给其子类完成。抽象类中可以有抽象方法(没有方法体),也可以有已实现的方法。

//抽象类
abstract class Animal{
    // 抽象方法-没有实现
    public abstract void makeSound();

    // 普通方法
    public void eat() {
        System.out.println("动物在吃东西");
    }
}

作用:用于表示通用的行为和属性,具体的实现由子类来完成

  • 不能实例化,只能通过继承来使用

  • 可以包含抽象方法(没有实现)和普通方法(有实现)

  • 子类必须实现抽象类的所有抽象方法,否则子类也必须是抽象的

(3)接口(Interface)

接口是一个纯抽象的类,它只定义方法的签名(方法名、参数和返回值),不包含方法的具体实现。接口用于定义类必须实现的功能。

interface Phone {
    void Call();  // 抽象方法
    
}

作用:接口定义类应该具备的行为,但不提供具体的实现,主要用于规范类的行为

  • 不能包含实例字段,只能有常量和抽象方法(Java 8 后可以有默认方法和静态方法)

  • 一个类可以实现多个接口(多重继承)

  • 所有方法都是 public 且 abstract,默认情况下接口中的方法就是抽象的

(4)内部类(Inner Class)

内部类是在另一个类中定义的类。内部类可以访问外部类的成员变量和方法,它主要用于逻辑上和外部类关联的类。

public class Outputs {
    private String message = "输出一个好消息";
 
    // 内部类
    class Inputs {
        public void displayMessage() {
            System.out.println(message);  // 可以访问外部类的成员变量
        }
    }
 
    public static void main(String[] args) {
        // 创建外部类对象
        Outputs outer = new Outputs();
        // 创建内部类对象
        Outputs.Inputs inner = outer.new Inputs();
        inner.displayMessage();  // 输出: 输出一个好消息
    }
}

作用:内部类用于封装与外部类紧密相关的功能,提供更好的封装性

  • 内部类可以访问外部类的所有成员变量和方法

  • 内部类对象的创建依赖于外部类对象

  • 内部类可以隐藏在外部类内部,增加了封装性和可读性

(5)静态内部类(Static Nested Class)

静态内部类是内部类的一种,但它不依赖于外部类的实例。静态内部类无法访问外部类的非静态成员。

public class OuterClass {
    private static String staticMessage = "来自静态嵌套类的Hello";
 
    // 静态内部类
    static class StaticNestedClass {
        public void displayMessage() {
            System.out.println(staticMessage);  // 只能访问外部类的静态变量
        }
    }
    
}

作用:用于逻辑上与外部类关联,但不依赖外部类实例的类

  • 静态内部类不能访问外部类的非静态成员变量

  • 静态内部类可以直接通过外部类名来创建对象

(6) 枚举类(Enum Class)

枚举类用于定义一组常量。它可以用于表示固定的常量集,如一周的天数、方向等。

enum Day {
    MONDAY, TUESDAY, WEDNESDAY;
}

public class Main {
    public static void main(String[] args) {
        Day monday = Day.MONDAY;
        Day tuesday = Day.TUESDAY;
        Day wednesday = Day.WEDNESDAY;
        switch (monday) {
            case MONDAY:
                System.out.println("Monday.");
                break;
            case TUESDAY:
                System.out.println("TUESDAY.");
                break;
            case WEDNESDAY:
                System.out.println("WEDNESDAY.");
                break;
            default:
                System.out.println("NULL day.");
        }
    }
}

作用:用于定义常量的集合,如一周的天数、月份、方向等

  • 枚举类的所有实例都是常量,且在类加载时就被初始化

  • 可以有构造器、方法和字段

4.类的成员?

使用static修饰的成员方法和成员变量称之为类成员。

使用static修饰的成员变量叫做类变量。

使用static修饰的成员方法叫做类方法。

未使用static修饰的成员方法和成员变量称为实例成员
未使用static修饰的成员变量叫做实例变量
未使用static修饰的成员方法叫做实例方法

public class Main {
    public String name;  //实例变量
    public static int age; //类变量

    public void init(){
        //实例方法
    }

    public static void end(){
        //类方法
    }

}

实例变量和类变量的区别:

  • 所有该类的对象共享同一个类变量,但是每个对象都会有自己独特的实例变量

  • 所有该类的对象都能改变类变量的值,但是每个对象只能改变自己的实例变量值

  • 实例变量在使用前必须创建一个对象,根据对象名.变量名使用,但是类变量不需要创建对象

类方法和实例方法的区别:

  • 所有该类对象共享类方法和实例方法

  • 类方法使用类名.方法名(参数)调用即可,不需要实例化对象后使用

  • 实例方法使用对象名.方法名(参数)调用

二、Java中类的使用
1.类的使用定义

使用class关键字定义的均属于是类。

public class Person {
    //这就定义好了Person这个类
    //这个类中就可以定义属性和行为
    //这里可以写成员变量和成员方法
    
}
2.类中成员变量声明

什么是成员变量?在类中定义的变量均属于是成员变量,还可以直接赋值。

public class Person {
    //这就定义好了Person这个类
    //这里可以写成员变量和成员方法
    //这里均是可以自定义的哟

    String name; //名字
    int age;    //年龄
    int phone;  //电话
    int gender; //性别 性别使用int型来表示 1男 0女
//以上定义是类的属性
}
3.类中成员方法声明
public class Person {
    //这就定义好了Person这个类
    //这里可以写成员变量和成员方法
    //

    String name; //名字
    int age;    //年龄
    int phone;  //电话
    int gender; //性别 性别使用int型来表示 1男 0女

    public void test(){  //成员方法
        System.out.println("姓名:"+name);
        System.out.println("年龄:"+age);
        System.out.println("电话:"+phone);
        System.out.println("性别:"+gender);
    }
    //在主方法中调用这个方法即可输出内容
}
4.创建对象

可以使用类创建对象

语法:

                变量名 = new 类类型名();

public class Person {
    //这就定义好了Person这个类
    //这里可以写成员变量和成员方法
    //

    String name; //名字
    int age;    //年龄
    int phone;  //电话
    int gender; //性别 性别使用int型来表示 1男 0女

    public void test(){  //成员方法
        System.out.println("姓名:"+name);
        System.out.println("年龄:"+age);
        System.out.println("电话:"+phone);
        System.out.println("性别:"+gender);
    }
    //主方法中创建对象直接调用使用
    public static void main(String[] args) {
        Person per = new Person();  //创建对象
        
        per.name = "小安";  //初始化
        per.age = 24;
        per.phone = 1845453244;
        per.gender = 1;
        per.test();  //调用类中方法 
        
        //当调用方法时可以传入参数的,这里是不需要参数所以没有传参数
    }
}

运行结果:

三、方法重载和方法重写
1.方法重载(Overload)

定义:在同一个类中有相同的方法名但是有不同的参数列表,就表示为方法重载。

注意喽!!!和返回类型是没有关系的哟

注意事项:每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。最常用的地方就是构造器的重载。

// 两个整数相加 int型数相加
    int add(int num1,int num2){
        return num1 + num2;
    }
    // 两个整数相加 float浮点型相加
    float add(float num1,float num2){
        return num1 + num2;
    }
    // 两个整数相加 double浮点型相加
    double add(double num1,double num2){
        return num1 + num2;
    }

//三个方法的名字都是相同的,但是需要传入的参数不同,这样就是方法的重载

2.方法重写(Override)

本来重写需要到后面的继承才和大家了解,但是也可以先了解了解基础,哈哈哈

定义:重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

好处:重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

//重写发生在继承关系中
class Dog{
    public void bark(){
        System.out.println("woof");
    }
}
class Hound extends Dog{
    public void sniff(){
        System.out.println("sniff");
    }
    public void bark(){
        System.out.println("bow1");
    }
}
3.方法重载和方法重写区别

(1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
(2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
(3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

图解更容易了解

4.构造方法使用

定义:Java语言通过类的构造方法构建对象,构造方法与普通方法的声明类似,但是构造方法有一些特征:构造器的名称必须与类名相同。

作用:一般用来初始化成员属性和成员方法的,即new对象产生后,就调用了对象的属性和方法。构造函数是对象一建立就运行,给对象初始化,就包括属性,执行方法中的语句。

public class Student {
    //学生类
    String name;
    public Student(){  //这就是一个无参构造方法
        System.out.println("这就是无参构造方法");
    }
    public Student(String name){  //这就是有参构造方法
        System.out.println("这就是有参构造方法");
    }
    //在new对象的时候就可以直接传值
    Student stu = new Student("小安");
}

使用场景:构造方法除了用于实例化对象之外,可以通过构造方法为成员变量赋值。

四、类的修饰符、控制符
1.非访问控制符

this关键字:指代当前对象实例

this是一种特殊的引用,指向当前对象

如果发生局部变量可以成员变量命名冲突时,可以通过this.成员变量名的方式区分实例变量和局部变量。

一个构造方法中需要调用同一个类的另一个构造方法,可以通过this()的方式调用,但this()必须要书写在第一行。

public class Student {
    //学生类
    String name;
    

    // 当传入一个name值后,我们需要把这个值传到全局变量内使用
    // 如果不加this,则name将会与这个方法里面的name进行匹配赋值,因为在方法内是属于局部变量
    // 所以我们在接收变量前加上this关键字后,指的就是全局变量
    public Student(String name){
        this.name = name;
    }
}

static关键字:表示类级别的成员(属性和方法)

静态的,非实例的,类的可以修饰内部类,也可以修饰成员

static关键字:

Java类提供了两种类型的变量,用static关键字修饰的静态变量和不用static关键字修饰的实例变量。

静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载。

静态变量就会被分配空间,因此就可以被使用了。对静态变量的引用有两种方式,分别是“类.静态变量"和”对象.静态变量"

static成员方法:
static方法是的方法,不需要创建对象就可以被调用,而非static方法是对象的方法,只有对象被创建出来后才可以被使用。

static方法中不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员变量和成员方法,因为当static方法被调用时,这个类的对象可能还没被创建,即使已经被创建了,也无法确定调用哪个对象的方法。

static用处:

  • 修饰成员变量

  • 修饰成员方法

  • 静态代码块

  • 修饰类【只能修饰内部类也就是静态内部类】

  • 静态导包

static注意事项:
静态只能访问静态,非静态既可以访问非静态的,也可以访问静态的。

public class Student {
    static Integer id;   //学号
    static String name;  //姓名

    Student(Integer id,String name){
        this.id = id;
        this.name = name;
    }
}


class Person {
    public static void main(String[] args) {
        Student stu = new Student(10001, "小安");

        System.out.println(stu.id);    //用一个实例化的对象来访问类中static字段
        System.out.println(stu.name);

        System.out.println(Student.id); //这里可以用类名来直接访问类中static字段
        System.out.println(Student.name);
    }
}

final关键字:表示不可修改的常量或不可继承的类/不可重写的方法

最终的,不可改变的可以修饰类,成员,局部变量

final类:如果一个类被final修饰符所修饰和限定,说明这个类不能被继承,即不会拥有子类。

final方法:final修饰符所修饰的方法,是不能被子类所覆盖的方法。

final字段和final局部变量:它们的值一旦给定,就不能更改。并且它们是只读量,它们能且只能被赋值一次,不能多次赋值。

如果一个字段被 static final 同时修饰时,它可以表示常量。如果不给定初始值,则按默认值进行初始化(数值为0,boolean类型为false,引用类型为null)。

public class TestClass {
    public static void main(String[] args) {
        MyClass myClass1 = new MyClass();
        MyClass myClass2 = new MyClass();

        System.out.println(myClass1.i);
        System.out.println(myClass1.j);
        System.out.println(myClass2.i);
        System.out.println(myClass2.j);

    }
}

class MyClass{
    public final double i = Math.random(); //用final修饰的
    public static double j = Math.random(); //用static修饰
}

abstract关键字:抽象的,不可实例化的可以修饰 类,成员

  • 凡是用abstract修饰符修饰的类被称为抽象类。

  • 抽象类不能被实例化。

  • 抽象类方法在子类中必须被实现,否则子类仍然是abstract的。

1.用abstract关键字来表达的类,其表达式为:(public) abstract class 类名{ ... }
2.抽象类不能实例化,我们没法直接new一个抽象类。抽象类的本身就代表了一个类型,无法具体确定为一个具体的对象,只有他的继承类可以被实例化。
3.抽象类虽然不能被实例化,但有自己的构造方法。
4.抽象类与接口(interface)有很大的不同之处,接口中不能有实例方法去实现业务逻辑,而抽象类中可以有实例方法,并实现业务逻辑。
5.抽象类不能用final关键字修饰。

优点:

由于抽象类不能被实例化,最大的好处就是通过方法的覆盖来实现多态的属性。也就是运行期绑定。
抽象类将事物的共性的东西提取出来,由子类继承去实现,代码易扩展、易维护。

简单的例子:

//员工实体类
public abstract class Employee {
    private int id;
    private String name;
    private int age;

    public Employee(int id, String name,int age) {
        this.id=id;
        this.name = name;
        this.age =age;
    }
    public int getId() {
        return this.id;
    }
    public String getName() {
        return this.name;
    }
    public int getAge() {
        return this.age;
    }
    public abstract double getSalary();

}
//工资实体类
public class Salary extends Employee {
    private double salary;

    public Salary(int id,String name,int age,double salary) {
        super(id,name,age);
        setSalary(salary);
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public double getSalary(){
        return this.salary;
    }
}
public class Test {
    public static void main(String[] args) {
        //通过自身的非抽象子类来实例化对象
        Employee a=new Salary(1,"小安",25,3600.00);
        //非抽象子类可以实例化对象
        Salary b=new Salary(2,"小王",30,4500.00);

        System.out.println("第"+a.getId()+"个,姓名为:"+a.getName()+", 年龄为:"+a.getAge()+", 工资为:"+a.getSalary());
        System.out.println("第"+b.getId()+"个,姓名为:"+b.getName()+", 年龄为:"+b.getAge()+", 工资为:"+b.getSalary());

    }
}

运行结果:

2.可访问修饰符

(1)public: 所有类可见

访问范围最广,一般都可以访问

(2)protected: 同包或子类可见

可以在同一个类中,同一个包中,和不同包中的子类中被访问

(3)default (默认): 同包可见

如果不加修饰符,则只能在同一个类和同一个包中,这2种情况下访问:

类的访问控制符为public或者默认,如果类用public修饰,则该类可以被其他类所访问,如果类是默认访问控制符,则该类只能被同包中的类访问。

(4)private: 仅本类可见

只能在同一个类中被访问

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值