首页 > 编程语言 >day07 7.1 Java中的面向对象之类与对象

day07 7.1 Java中的面向对象之类与对象

时间:2023-07-16 15:22:57浏览次数:46  
标签:Java name void day07 System 7.1 println public out

day07 7.1 Java中的面向对象之类与对象

【一】类与对象

【1】类定义规范

  • 类与对象的关系
    • 类 是实体对象的概念模型,笼统的,不具体的,
      • 比如人类、动物类、鸟类
    • 对象 又称为实体,类具体化的表现
      • 小红/小明
      • 小猫一号/小狗一号
    • 对象中有属性,有方法
      • 不同对象属性是独有的
      • 方法是共有的
  • 类定义规范
// [] :内的内容可以不写  | :左右的内容表示或

[public][abstract|final] class 类名class_name [extends 继承的类名] [implements 实现的接口名]{
    // 定义成员属性
    属性类型1 属性名1; // String name;
    属性类型2 属性名2; // int age;
        
    // 定义静态属性(类属性)
    private String name;
        
    // 定义类成员方法
    public int add(int a, int b){
        return a+b;
    }
    
    // 定义静态方法(类方法)
    public static void speak(){
        System.out.println("说话")
    }
}

public:表示类是公有的

java文件的文件名必须是public class 类名

abstract:抽象类

final:类如果被 final 修饰 ,这个类不能被别的类所继承

extends:继承某个父类

implements:实现的接口

(1)类的定义

public class Person {
    // 定义成员属性
    private String name;
    // 定义成员属性
    public int age;
    // 定义静态属性
    public static int sex;

    // 定义类成员方法
    // void:方法没有返回值
    public void speak() {
        System.out.println("说话了!");
    }

    // 静态方法
    public static run() {
        System.out.println("跑起来了!");
    }

}

(2)对象的实例化

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

public class Demo01 {

    public static void main(String[] args) {
        // 因为在同一个包下,所以可以直接引用
        // (1)实例化类对象 p
        Person p = new Person();

        // (2)修改对象属性
        // 由于 name 是由 private 修饰
        // 所以无法通过对象 修改该属性
        p.age = 18;
        System.out.println(p);
        // Person@1b6d3586
        
        // (3)调用对象方法
        p.speak();
        // 说话了!
    }
}

【2】Java的类属性

  • 在类中有属性
    • 成员属性
      • 只要不被static修饰的,就是成员属性,他是属于对象的,需要对象来调用
    • 静态变量
      • 只要 static修饰的,需要类或类实例的对象来调用
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

//public class Demo01 {
//
//    public static void main(String[] args) {
//        // 因为在同一个包下,所以可以直接引用
//        // (1)实例化类对象 p
//        Person p = new Person();
//
//        // (2)修改对象属性
//        // 由于 name 是由 private 修饰
//        // 所以无法通过对象 修改该属性
//        p.age = 18;
//        System.out.println(p);
//        // Person@1b6d3586
//
//        // (3)调用对象方法
//        p.speak();
//        // 说话了!
//    }
//}

public class Demo01 {

    public static void main(String[] args) {
        // 类属性

        // (1)实例化类得到类对象
        Person p = new Person();
        // 对象的属性 ----> 不被static修饰的
        p.hobby = "music";
        p.age = 18;

        Person p1 = new Person();
        // 对象的属性 ----> 不被static修饰的
        p1.hobby = "sport";
        p1.age = 29;

        // 每个对象都有自己的属性,因此打印的内容不一样
        System.out.println(p.hobby);
        System.out.println(p1.hobby);

        // (2)静态成员:被static修饰的,属于类
        // 通过对象,修改静态成员,但是他是属于类的,都会受影响
        p.sex = 2;
        p1.sex = 1;
        System.out.println(p.sex);
        // 2
        // 1
        System.out.println(p1.sex);
        // 2
        // 1

        // 类来修改静态属性,一般是用类来修改静态属性
        Person.sex = 3;
        System.out.println(p.sex);
        // 3
        System.out.println(p1.sex);
        // 3

    }
}
public class Person {
    // 定义成员属性
    private String name;
    // 定义成员属性
    public String hobby;
    public int age;
    // 定义静态属性
    public static int sex;

    // 定义类成员方法
    // void:方法没有返回值
    public void speak() {
        System.out.println("说话了!");
    }

    // 静态方法
    public static void run() {
        System.out.println("跑起来了!");
    }

}

  • 在Python中年对象的属性只能对象来调用
  • 在Python中年类的属性只能类来调用

【3】成员方法

  • 类中没有被static修饰的方法,绑定给类的,需要类来调用。
  • Python中有绑定给对象的方法,绑定给类的方法

    • Python的类中,不加任何装饰器的的方法是绑定给对象的

      java:public void Speak(){}
      
    • Python的类中,使用@classmethod修饰的,是绑定给类的方法

      java:public static void Speak(){}
      

public class Demo01 {

    public static void main(String[] args) {
        // 静态方法和成员方法
        Person p = new Person();

        p.speak(); // 对象的方法
        
//        p.run();//类的方法,正常不是对象来调用,而是类来调用
        Person.run();

    }
}
public class Person {
    // 定义成员属性
    private String name;
    // 定义成员属性
    public String hobby;
    public int age;
    // 定义静态属性
    public static int sex;

    // 定义类成员方法
    // void:方法没有返回值
    // 没有被 static 修饰
    public void speak() {
        System.out.println("说话了!");
    }

    // 静态方法
    // 被 static 修饰
    public static void run() {
        System.out.println("跑起来了!");
    }

}

【4】构造方法

  • 在Python中

    __init__方法完成对象的初始化

  • 在Java中

    完成对对象的初始化,向对象中添加内容

    可以存在多个,使用哪种初始化方式,就会触发那种构造方法

public class Demo01 {

    public static void main(String[] args) {
        // 构造方法

        // (1)触发无参构造方法
        Person person = new Person();
        // 实例化对象,但是不向对象中添加参数
        // 会触发Person类的无参构造方法,完成初始化
        // 一旦执行,person中的 name 就完成了初始化 变成了 dream
        System.out.println(person.name);
        // 我正在开始执行!
        // dream

        // (2)触发有参构造方
        Person p = new Person("mengmeng");
        System.out.println(p.name);
        // 我是有参构造方法,形参为1个
        // mengmeng

        // (3)触发有参构造方法
        Person p1 = new Person("CHIMENG", 19);
        System.out.println(p1.name);
        System.out.println(p1.age);
        // 我是有参构造方法,形参为2个
        // CHIMENG
        // 19



    }
}
public class Person {
    // 定义成员属性
//    private String name;
    // 定义成员属性
    public String hobby;
    public String name;
    public int age;
    // 定义静态属性
    public static int sex;

    // 定义类成员方法
    // void:方法没有返回值
    // 没有被 static 修饰
    public void speak() {
        System.out.println("说话了!");
    }

    // 静态方法
    // 被 static 修饰
    public static void run() {
        System.out.println("跑起来了!");
    }

    // 构造方法
    // 无参构造方法
    public Person() {
        System.out.println("我正在开始执行!");
        this.name = "dream";
    }

    // 有参构造方法
    public Person(String name) {
        System.out.println("我是有参构造方法,形参为1个");
        this.name = name;
    }

    // 有参构造方法
    public Person(String name, int age) {
        System.out.println("我是有参构造方法,形参为2个");
        this.name = name;
        this.age = age;
    }
}

【5】this关键字

  • this是写在类中的成员(对象)方法中
  • [static修饰的方法中,即静态方法中,没有this]
public class Demo01 {

    public static void main(String[] args) {
        // 构造方法

        // (1)触发无参构造方法
        Person person = new Person();
        // 实例化对象,但是不向对象中添加参数
        // 会触发Person类的无参构造方法,完成初始化
        // 一旦执行,person中的 name 就完成了初始化 变成了 dream
        System.out.println(person.name);
        // 我正在开始执行!
        // dream

        // (2)触发有参构造方
        Person p = new Person("mengmeng");
        System.out.println(p.name);
        // 我是有参构造方法,形参为1个
        // mengmeng

        // (3)触发有参构造方法
        Person p1 = new Person("CHIMENG", 19);
        System.out.println(p1.name);
        System.out.println(p1.age);
        // 我是有参构造方法,形参为2个
        // CHIMENG
        // 19

        // this 触发
        // 谁调用方法就是谁
        person.Sleep();
        //dream
        //睡觉中.....
        p.Sleep();
        //mengmeng
        //睡觉中.....
        p1.Sleep();
        //CHIMENG
        //睡觉中.....

    }
}
public class Person {
    // 定义成员属性
//    private String name;
    // 定义成员属性
    public String hobby;
    public String name;
    public int age;
    // 定义静态属性
    public static int sex;

    // 定义类成员方法
    // void:方法没有返回值
    // 没有被 static 修饰
    public void speak() {
        System.out.println("说话了!");
    }

    // 静态方法
    // 被 static 修饰
    public static void run() {
        System.out.println("跑起来了!");
    }

    // 构造方法
    // 无参构造方法
    public Person() {
        System.out.println("我正在开始执行!");
        this.name = "dream";
    }

    // 有参构造方法
    public Person(String name) {
        System.out.println("我是有参构造方法,形参为1个");
        this.name = name;
    }

    // 有参构造方法
    public Person(String name, int age) {
        System.out.println("我是有参构造方法,形参为2个");
        this.name = name;
        this.age = age;
    }

    // this 关键字
    public void Sleep() {
        System.out.println(this.name);
        System.out.println("睡觉中.....");
    }    

}

【6】访问控制符

访问范围 private friendly(默认) protected public
同一个类 可访问 可访问 可访问 可访问
同一包中的其他类 不可访问 可访问 可访问 可访问
不同包中的子类 不可访问 不可访问 可访问 可访问
不同包中的非子类 不可访问 不可访问 不可访问 可访问
//1  private
用 private 修饰的类成员,只能被该类自身的方法访问和修改,而不能被任何其他类(包括该类的子类)访问和引用。因此,private 修饰符具有最高的保护级别
  
//2 friendly(默认)
如果一个类没有访问控制符,说明它具有默认的访问控制特性。这种默认的访问控制权规定,该类只能被同一个包中的类访问和引用,而不能被其他包中的类使用,即使其他包中有该类的子类。这种访问特性又称为包访问性(package private)

//3  protected
用保护访问控制符 protected 修饰的类成员可以被三种类所访问:该类自身、与它在同一个包中的其他类以及在其他包中的该类的子类。使用 protected 修饰符的主要作用,是允许其他包中它的子类来访问父类的特定属性和方法,否则可以使用默认访问控制符。
  
//4 public
当一个类被声明为 public 时,它就具有了被其他包中的类访问的可能性,只要包中的其他类在程序中使用 import 语句引入 public 类,就可以访问和引用这个类

【7】静态变量和静态方法(static)

在类中,使用static修饰的变量是属于类的,正常类来调用,但是对象也可以调用

在类中,使用static修饰的方法是属于类的,正常类来调用,不需要实例化,就能调用,但是对象也可以调用,但是他的内部没有this关键字

什么情况下定义对象的方法[成员方法]

什么情况下定义类的方法[静态方法]

以后,不想初始化得到对象就能使用这个方法,就定义成静态方法。

(1)什么是静态变量(类变量)

  • 在类中,使用 static 修饰符修饰的属性(成员变量)称为静态变量,也可以称为类变量
    • 常量称为静态常量
    • 方法称为静态方法或类方法
  • 它们统称为静态成员,归整个类所有。
    • 静态成员不依赖于类的特定实例,被类的所有实例共享
    • 就是说 static 修饰的方法或者变量不需要依赖于对象来进行访问
    • 只要这个类被加载,Java 虚拟机就可以根据类名找到它们

(2)什么是静态变量

  • 类的成员变量可以分为以下两种:
    • 静态变量(或称为类变量),指被 static 修饰的成员变量
    • 实例变量,指没有被 static 修饰的成员变量
  • 静态变量与实例变量的区别如下:

  • 1)静态变量

    • 运行时,Java 虚拟机只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配

    • 在类的内部,可以在任何方法内直接访问静态变量

    • 在其他类中,可以通过类名访问该类中的静态变量

  • 2)实例变量

    • 每创建一个实例,Java 虚拟机就会为实例变量分配一次内存

    • 在类的内部,可以在非静态方法中直接访问实例变量

    • 在本类的静态方法或其他类中则需要通过类的实例对象进行访问

(3)什么是静态方法

  • 类的成员方法也可以分为以下两种:
    • 静态方法(或称为类方法),指被 static 修饰的成员方法
    • 实例方法,指没有被 static 修饰的成员方法
  • 静态方法与实例方法的区别如下:
    • 静态方法不需要通过它所属的类的任何实例就可以被调用
    • 因此在静态方法中不能使用 this 关键字,也不能直接访问所属类的实例变量和实例方法
    • 但是可以直接访问所属类的静态变量和静态方法。
    • 另外和 this 关键字一样, super 关键字也与类的特定实例相关
    • 所以在静态方法中也不能使用 super 关键字
    • 在实例方法中可以直接访问所属类的静态变量、静态方法、实例变量和实例方法

【二】面向对象之继承

【1】继承格式

  • 在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:

    class 父类 {
    }
     
    class 子类 extends 父类 {
    }
    class 子子类 extends 子类 {
    }
    
  • Java中的继承

    • 只支持单继承,不支持多继承,但支持实现多个接口
    • 支持一条线上的多重继承
  • Java不支持多继承,但是可以通过接口来实现多继承的功能

【2】构造方法

(1)分文件继承

  • 构造Animal类
public class Animal {
    String name;
}
  • 构造Dog类
public class Dog  extends Animal {
    int age;
    // 有参构造
    public Dog(String name,int age){
        this.name = name;
        this.age = age;

    }
}
  • 实例化调用
public class Demo01 {

    public static void main(String[] args) {
        // 继承的关系测试

        // 实例化得到一个DOG对象
        // Dog = new Dog(); // 没有参数传入会报错,因为Dog内部是一个有参构造方法
        Dog d = new Dog("dream", 18);
        System.out.println(d.name); // dream

    }
}

(2)单文件继承

在一个文件中只能有一个 public 方法

class Animal {
    String name;
}

class Dog  extends Animal {
    int age;
    // 有参构造
    public Dog(String name,int age){
        this.name = name;
        this.age = age;

    }
}

public class Demo01 {

    public static void main(String[] args) {
        // 继承的关系测试

        // 实例化得到一个DOG对象
        // Dog = new Dog(); // 没有参数传入会报错,因为Dog内部是一个有参构造方法
        Dog d = new Dog("dream", 18);
        System.out.println(d.name); // dream

    }
}

(3)小结

  • 子类如果没写构造方法
    • 默认使用父类无参构造
  • 本案例名字为:固定名字
// 1 子类如果没写构造方法,默认使用父类无参构造,本案例名字为:固定名字
// 2 子类如果没写构造方法,不会自动使用父类的有参构造,所以Person p=new Person("justin");用法是报错的
import java.util.*;


public class Demo04 {
    public static void main(String[] args) throws Exception {

        Person p=new Person("justin");
        p.Speak();
        System.out.println(p.name);

    }

}

class Animal{
    String name;
    public Animal(){
        this.name="固定名字";
    }
    public Animal(String  name){
        this.name=name;
    }

    public void Speak(){
        System.out.println("动物说话");

    }
}

class Person extends Animal {
    int age;
    // 子类如果没写构造方法,默认使用父类无参构造,本案例名字为:固定名字
    // 子类如果没写构造方法,不会自动使用父类的有参构造,所以Person p=new Person("justin");用法是报错的
    //    public Person(String name,int age){
    //        this.name=name;
    //        this.age=age;
    //    }
    public void Run(){
        System.out.println("人走路");
    }

    @Override
    public void Speak(){
        super.Speak(); // 代指父类对象,等同于python的super()
        System.out.println("人说话");

    }
}

【3】super 与 this 关键字

有了继承关系就会多了另一个关键字(原来有this):super(等同于python中的super())

  • super关键字:
    • 我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类
  • this关键字:指向自己的引用
class Animal{
    String name;
    public void Speak(){
        System.out.println("动物说话");

    }
}
class Person extends Animal {
    int age;
    public void Run(){
        System.out.println("人走路");
    }

    @Override
    public void Speak(){
        this.Speak(); // 代指自己的,先从自己找,自己没有去父类找
        super.Speak(); // 代指父类对象,等同于python的super(),直接去父类找
        System.out.println("人说话");

    }
}

【三】重写(Override)与重载(Overload)

【1】什么是重写

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

【2】什么是重载

  • 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。

  • 返回类型可以相同也可以不同

  • 被重载的方法必须改变参数列表(参数个数或类型不一样)

【3】演示

class Animal{
    String name;
    public Animal(){
        this.name="固定名字";
    }
    public Animal(String  name){
        this.name=name;
    }

    public void Speak(){
        System.out.println("动物说话");

    }
}
class Person extends Animal {
    int age;
    public void Run(){
        System.out.println("人走路");
    }
    // 重载方法 - 方法名一样,参数不一样
    public void Run(String ss){
        System.out.println(ss);
        System.out.println("走路");
    }
    // 重写方法Speak - 必须有继承关系
    @Override
    public void Speak(){
        super.Speak(); // 代指父类对象,等同于python的super()
        System.out.println("人说话");
    }

    // 重载方法Speak
    public void Speak(String aa){
        super.Speak(); // 代指父类对象,等同于python的super()
        System.out.println("人说话");

    }
}

【四】面向对象之接口

【1】接口的介绍

(1)接口是一个抽象类型

  • 接口(Interface),是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。
  • 一个类通过继承接口的方式,从而来继承接口的抽象方法。

只在接口中定义某个方法,可以不写这个方法,意思是继承接口的类必须要有我定义的接口中的方法

(2)接口并不是类

  • 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。
  • 类描述对象的属性和方法。接口则包含类要实现的方法。

(3)接口无法被实例化,但是可以被实现

  • 一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。
  • 接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口不支持被 new

(4)接口与类相似点

  • 一个接口可以有多个方法
  • 接口文件保存在 .java 结尾的文件中,文件名使用接口名

(5)接口与类的区别

  • 接口不能用于实例化对象
  • 接口没有构造方法
  • 接口中所有的方法必须是抽象方法
  • 接口不能包含成员变量,除了 static 和 final 变量
  • 接口不是被类继承了,而是要被类实现
  • 接口支持多继承
    • 类可以实现多个接口

【2】接口声明

  • 定义接口语法
public interface 接口名 extends 其它接口 {
    // 声明变量 static 和 final 变量
    // 声明方法,抽象方法
    public Speak(); // 不用加{},这里只是定义了一个接口方法,而没有具体实现这个方法,所以不用加{}
}
  • 官方一点的写法
[可见度] interface 接口名称 [extends 其他的接口名] {
        // 声明变量
        // 抽象方法
}
  • 示例
  • 接口
interface Duck {
    //任何类型 final, static 字段
    final String name="dream";
    public static int age = 19;

    //抽象方法
    public void Speak();
    //public void Run(){}; // 不能有具体实现
    public void Run(); // 不能有具体实现
}
  • 子类中实现接口
// 子类实现接口,必须实现接口中所有的方法
class TDuck implements Duck {

    @Override
    public void Speak() {
        System.out.println("鸭子叫");
    }

    @Override
    public void Run() {
        System.out.println("鸭子走路");
    }
}
  • python中的鸭子类型
    • 只要我的方法中有这两个方法,就是同一类
class TDuck():
	def speak():
    	pass
    def run():
        pass

class RDuck():
	def speak():
    	pass
    def run():
        pass
  • Java中的鸭子类型
    • 在Java中必须实现继承的同一个接口的两个类才叫鸭子类型,是同一类
interface Duck {
    //任何类型 final, static 字段
    final String name = "dream";
    public static int age = 19;

    //抽象方法
    public void Speak();

    //public void Run(){}; // 不能有具体实现
    public void Run(); // 不能有具体实现
}

// 子类实现接口,必须实现接口中所有的方法
class TDuck implements Duck {

    @Override
    public void Speak() {
        System.out.println("唐老鸭鸭子叫");
    }

    @Override
    public void Run() {
        System.out.println("唐老鸭鸭子走路");
    }
}

class RDuck implements Duck {

    @Override
    public void Speak() {
        System.out.println("肉鸭鸭子叫");
    }

    @Override
    public void Run() {
        System.out.println("肉鸭鸭子走路");
    }
}

【3】接口继承

  • 可以继承多个接口
interface Duck {
    public void Speak();
    public void Run();
}

interface TDuck extends Duck{
    public void Flay();
}

// 接口的多继承:在Java中,类的多继承是不合法,但接口允许多继承。在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口
interface Foo extends Duck, TDuck{
}

【4】接口实现

  • 可以实现多个接口
// 实现接口,必须实现接口中所有的方法
interface Duck {
    //抽象方法
    public void Speak();
    public void Run(); // 不能有具体实现
}

interface TDuck extends Duck{
    public void Flay();
}
class RealDuck implements TDuck{

    @Override
    public void Speak() {
        
    }

    @Override
    public void Run() {

    }

    @Override
    public void Flay() {

    }
}

【五】面向对象之抽象类

  • 定义格式
public abstract class Foo{
    // 定义方法
    public void Speak(){
         System.out.println("Speak Speak Speak");
    }
    // 定义抽象方法
    public abstract void Sleep();
}

// 继承

class Bird extends Foo {
    // Speak 已经有具体实现了,可以不重写
    // 但是Sleep必须重写,因为没有实现
    @Override
    public void Sleep() {
        System.out.println("必须重写抽象方法");
    }
}
  • 案例演示
public class Demo04 {
    public static void main(String[] args) {
        Bird b = new Bird();
        b.Speak(); // Speak Speak Speak
        b.Sleep(); // 必须重写抽象方法
    }
}


abstract class Foo {
    // 定义方法
    public void Speak() {
        System.out.println("Speak Speak Speak");
    }

    // 定义抽象方法
    public abstract void Sleep();
}

// 继承
class Bird extends Foo {
    // Speak 已经有具体实现了,可以不重写
    // 但是Sleep必须重写,因为没有实现
    @Override
    public void Sleep() {
        System.out.println("必须重写抽象方法");
    }
}

【六】抽象类和接口的区别

【小结】

  • 关键字不一样

  • 类继承是 implements extends

  • 类是类,接口是接口

  • 抽象类中方法可以具体实现,但是接口不能有具体实现

  • 一个类可以实现多个接口,但是不能继承多个类

【详解】

  • 关键字不同:

    • 在Java中,使用abstract关键字定义抽象类

    • 使用interface关键字定义接口。

  • 形式上的区别:

    • 类可以继承一个类,但类不能继承多个类

    • 一个类可以实现多个接口。

  • 方法的实现:

    • 抽象类可以包含具体的方法实现

      • 这些方法可以被子类继承和重写,也可以直接被调用。
    • 接口只能定义方法的签名

      • 不能包含方法的实现,实现接口的类必须提供接口中定义的所有方法的具体实现。
  • 字段的定义:

    • 抽象类可以定义实例变量

      • 这些变量可以是任意的访问修饰符,并且可以有默认值。
    • 接口只能定义常量字段(static final

      • 而且字段默认为公共、静态和最终。
  • 设计思想:

    • 抽象类用于表示一种通用的父类

      • 其中包含了子类所共有的属性和方法。
    • 接口则用于定义一组行为和功能的规范

      • 不关心具体实现细节,只关注方法的输入和输出。
  • 总结来说
    • 抽象类更类似于普通类的扩展和继承
    • 接口更像是一种规范或者契约,用于描述类应该具有的行为和功能。
  • 在设计中,应根据具体的需求选择使用抽象类还是接口。
    • 如果需要表达一种"is-a"的关系并且需要共享代码实现
      • 可以使用抽象类;
    • 如果需要表达一种"has-a"的关系或者需要多继承
      • 可以使用接口。

【七】面向对象之封装

【1】面向对象三大特性

  • 继承

  • 多态

  • 封装

  • 封装

    • 把属性或方法放在类的内部,可以隐藏起来,然后拿到一个对象
    • 可以 .属性 .方法 进行使用

【2】在Java中,习惯把属性定义成私有的,然后提供方法,来进行读写

public class Demo05 {
    public static void main(String[] args) {
        // 实例化类对象
        Fish f = new Fish();
        f.name = "xxx"; // 这样做是不行的,因为类属性被定义为私有的属性,无法通过实例化对象调用去修改私有属性
    }
}

// 定义一个类
class Fish {
    // 类里面放了一个私有属性
    private String name;
}
  • 解决
public class Demo05 {
    public static void main(String[] args) {
        // 实例化类对象
        Fish f = new Fish();

        // 通过方法去修改设置属性 - 安全
        f.setName("小黄鱼");
        System.out.println(f.getName()); // 小黄鱼

    }
}

// 定义一个类
class Fish {
    // 类里面放了一个私有属性
    private String name;

    // Java 中习惯这样用
    // 开放接口方法,供外部修改调用
    public void setName(String name) {
        this.name = name;
    }

    // 开放接口方法,当外部访问时,可以将想要反出去内容返回
    public String getName() {
        return this.name;
    }

}
  • 支持自定义返回数据
public class Demo05 {
    public static void main(String[] args) {
        // 实例化类对象
        Fish f = new Fish();

        // 通过方法去修改设置属性 - 安全
        f.setName("小黄鱼");
        System.out.println(f.getName()); // 小黄鱼安全属性

    }
}

// 定义一个类
class Fish {
    // 类里面放了一个私有属性
    private String name;

    // Java 中习惯这样用
    // 开放接口方法,供外部修改调用
    public void setName(String name) {
        this.name = name;
    }

    // 开放接口方法,当外部访问时,可以将想要反出去内容返回
    public String getName() {
        // 支持返回的数据拼接其他的东西
        return this.name + "安全属性";
    }
}

【3】详解

// java中一般不直接通过对象调用属性,而是通过方法来设置和获取属性【更安全】
class Person {
    public String name ;
    private int age;
    public void setAge(int age){
        this.age=age;
    }
    public int getAge(){
        return this.age+1;
    }
}

【八】面向对象之多态

【1】什么是多态

  • 多态是同一类事物[实例,对象]多种形态
猫对象1号
狗对象1号
都属于动物类  --> 动物类(通过继承,实现多个接口),有多种具体形态
调用 同一类事物共有的方法 --> 虽然调用同样的方法,但是各自表现出来的不一样,狗是狗叫,猫是猫叫
  • 从而调用同一类[实例,对象]方法时,表现出不同

【2】多态存在的三个必要条件

  • (1)编写具有继承关系的父类和子类/接口实现
  • (2)子类重写父类方法
  • (3)使用父类的引用指向子类的对象
前面是父类 ---- 指向了具体的某一个类
Duck d = new Tduck()
	而不是
Tduck d = new Tduck()

【3】继承实现的多态

public class Demo06 {
    public static void main(String[] args) {
        // 多态
        // 实例化得到对象
        // 将具体的类赋值给父类
        Foo1 c1 = new Child1();
        Foo1 c2 = new Child2();

        // 调用方法
        c2.Run();
        c2.Speak();
        // c2.Sleep(); // c2是Foo1类型,Foo1没有 Sleep 方法,所以不能调用 Sleep 方法
        // 如果想调用必须要做类型转换
        Child2 cc2 = (Child2) c2;  // 强制转换数据类型
        cc2.Sleep(); // 转成具体类型,可以调用具体的独有的方法

        // c1 可以转换成 Child2 类型吗?
        // 不可以,每个对象有每个对象自己独有的类,不能将两个本质上不同的类强转成另一个类
        // 即 c1 本质上是 Child1 类型 , 不能强转成 Child2 类型

        // 强转类型建议加 If 判断
        if (c1 instanceof Child1) {
            Child1 cc1 = (Child1) c1;
        }


    }
}

// 定义父类
class Foo1 {
    public void Speak() {
        System.out.println("父类的Speak方法");
    }

    public void Run() {
        System.out.println("父类的Run方法");
    }
}

// 子类继承父类
class Child1 extends Foo1 {
    // 重写父类方法可以不写
    @Override
    public void Speak() {
        System.out.println("这是子类1中重写的 Speak 方法");
    }

    @Override
    public void Run() {
        System.out.println("这是子类1中重写的 Run 方法");
    }
}

class Child2 extends Foo1 {
    // 重写父类方法可以不写
    @Override
    public void Speak() {
        System.out.println("这是子类2中重写的 Speak 方法");
    }

    @Override
    public void Run() {
        System.out.println("这是子类2中重写的 Run 方法");
    }

    // 定义子类独有的方法
    public void Sleep() {  // 派生方法: 比父类方法多的方法叫派生方法
        System.out.println("这是子类2独有的 Sleep 方法");
    }
}
  • 子类转父类不叫强转,直接赋值给父类即可
  • 父类转子类需要强转,强转可能会出错

【4】其他知识详解

(1)多态成员变量编译运行看左边

public class Demo04 {
    public static void main(String[] args) throws Exception {
        // 1 多态成员变量:编译运行看左边
        Animal dog = new Dog();
        System.out.println(dog.age);
    }
}

//父类
class Animal {
    public int age = 11;
}
//子类
class Dog extends Animal {
    public int age = 33;

}

(2)多态成员方法:编译看左边,运行看右边

public class Demo04 {
    public static void main(String[] args) throws Exception {

        // 1 多态成员变量:编译运行看左边
        Animal dog = new Dog();
        System.out.println(dog.age);
        // 2 多态成员方法:编译看左边,运行看右边
        dog.eat();
    }
}

//父类
class Animal {
    public int age = 11;
    public void eat() {
        System.out.println("动物吃饭");
    }
}
//子类
class Dog extends Animal {
    public int age = 33;
    @Override
    public void eat() {
        System.out.println("狗吃饭");
    }
}

(3)子类增加独有方法walk()

import java.util.*;
import com.justin.*;
import com.justin.Db;
import com.justin.Helper;

public class Demo04 {
    public static void main(String[] args) throws Exception {

        // 1 多态成员变量:编译运行看左边
        Animal dog = new Dog();
        System.out.println(dog.age);

        // 2 多态成员方法:编译看左边,运行看右边
        dog.eat();
        // 3 无法调用子类独有方法
        //dog.walk();


    }
}

//父类
class Animal {
    public int age = 11;
    public void eat() {
        System.out.println("动物吃饭");
    }

}
//子类
class Dog extends Animal {
    public int age = 33;
    @Override
    public void eat() {
        System.out.println("狗吃饭");
    }
    public void walk() {
        System.out.println("狗走路");
    }

}

(4)引用类型转换

  • 1 向上转型:【儿子变父亲】
    • 多态本身是子类向父类向上转换(自动转换)的过程
    • 这个过程是默许的
    • 当父类引用指向一个子类对象时,就是向上转型
  • 2 向下转型:【父亲变儿子,需要强制转换】
    • 向下转型,强制类型转换
Dog dog1 = (Dog) dog;
dog1.walk();
  • 3 类型转换会出现【类型转换异常】
  • 4 instanceof 判断具体类型
import java.util.*;

import com.justin.*;
import com.justin.Db;
import com.justin.Helper;

public class Demo04 {
    public static void main(String[] args) throws Exception {

        // 强制类型转换会出错
        Animal cat = new Cat();
//        Dog d=(Dog)cat;
//        d.walk();

        // 通过instance判断再转
        if(cat instanceof Cat){
            Cat c=(Cat) cat;
            c.sleep();
        }



    }
}

//父类
class Animal {
    public int age = 11;

    public void eat() {
        System.out.println("动物吃饭");
    }


}

//子类
class Dog extends Animal {
    public int age = 33;

    @Override
    public void eat() {
        System.out.println("狗吃饭");
    }

    public void walk() {
        System.out.println("狗走路");
    }

}

class Cat extends Animal {
    public int age = 63;

    @Override
    public void eat() {
        System.out.println("猫吃饭");
    }

    public void sleep() {
        System.out.println("猫睡觉");
    }

}

(5)抽象类实现的多态

public class Demo04 {
    public static void main(String[] args) throws Exception {

        //  抽象类实现的多态
        Animal a=new Dog();
        a.eat();
        a.speak();

    }
}

//父类
abstract class Animal {
    abstract void speak();
    public void eat() {
        System.out.println("动物吃饭");
    }


}

//子类
class Dog extends Animal{
    // 必须重写虚类上的方法
    @Override
    void speak() {
        System.out.println("狗叫");
    }
}

(6)接口实现的多态

import java.util.*;

import com.justin.*;
import com.justin.Db;
import com.justin.Helper;

public class Demo04 {
    public static void main(String[] args) throws Exception {

        // 2 接口实现的多态
        Animal a=new Dog();
        a.speak();

    }
}


interface Animal {
    public void speak();

}

//子类
class Dog implements Animal{
    @Override
    public void speak() {
        System.out.println("狗叫");
    }
    public void eat() {
        System.out.println("狗吃");
    }
}

【九】枚举

  • Java 枚举是一个特殊的类,一般表示一组常量,
    • 一年的 4 个季节
    • 一年的 12 个月份
    • 性别有男,女,未知
import java.util.*;


public class Demo04 {
    public static void main(String[] args) throws Exception {
        // 1 简单使用
        System.out.println(Sex.Unknown);
        System.out.println(Sex.Male);

        // 2 更多使用
        System.out.println("枚举顺序值,"+Week.SUNDAY.ordinal());   // 0
        System.out.println(Week.MONDAY.id);
        System.out.println(Week.MONDAY.meaning);



    }

}

enum Sex {
    Male,
    Female,
    Unknown;
}

enum Week {
    SUNDAY(0, "星期日"),
    MONDAY(1, "星期一"),
    TUESDAY(2, "星期二"),
    WEDNESDAY(3, "星期三"),
    THURSDAY(4, "星期四"),
    FRIDAY(5, "星期五"),
    SATURDAY(6, "星期六");
    public int id;
    public String meaning;

    Week(int id, String meaning) {
        this.id = id;
        this.meaning = meaning;
    }
}

【十】包(package)

【1】什么是包

  • 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

我们可以定义很多包

不同包下,类名可以重复

同一个包下,类名不能重复

【2】包的作用

  • 1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用

  • 2、同文件夹一样,包采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。

  • 3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

【3】创建包

// 右键,新建包----》其实就是文件夹
	com.dream
 
// 在包中定义类
com.dream
	Db.java
	Helper.java 
  • Helper.java
// 先声明是哪个包下的类(功能)
package com.dream;
public class Helper {
    public int add(int a ,int b){
        return a+b;

    }
}

【4】引入包,并使用包中的类

// 导入包下的所有类
import com.dream.*;

// 单独导入指定的包
import com.dream.Db;
import com.dream.Helper;

public class Demo04 {
    public static void main(String[] args) throws Exception {
        // 实例化的到dream类
        Helper h=new Helper();
        System.out.println(h.add(4,5));
    }
}

标签:Java,name,void,day07,System,7.1,println,public,out
From: https://www.cnblogs.com/dream-ze/p/17557889.html

相关文章

  • JavaScript:将对象数组映射到字典
    JavaScript:将对象数组映射到字典#javascript#打字稿#数据在JavaScript/TypeScript中将对象数组转换为字典的最简单方法:letdata=[{id:1,country:'Germany',population:83623528},{id:2,country:'Austria',population:8975552},{id:3,country......
  • Java性能优化-测试数组和链表在查询和添加删除时性能对比
    场景Java中使用JMH(JavaMicrobenchmarkHarness微基准测试框架)进行性能测试和优化:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131723751上面在使用JMH时测试了Java中数组和链表在进行头部插入时的对比结果。下面分别对比在头部、中部、尾部分别进行查询和......
  • Java在指定位置添加字符串
    Java在指定位置添加字符串的实现作为一名经验丰富的开发者,我很乐意教会刚入行的小白如何在Java中实现在指定位置添加字符串的操作。在本篇文章中,我将按照以下步骤详细说明整个实现过程:获取原始字符串创建一个StringBuilder对象使用StringBuilder的insert()方法在指定位置插入......
  • Java语言支付代码
    Java语言支付代码引言随着电子商务的迅速发展,支付功能成为了每个电商平台必备的功能之一。在Java语言中,开发者可以使用各种支付SDK和API来实现支付功能。本文将介绍Java语言中支付代码的基本原理,并提供一些示例代码以帮助读者更好地理解。支付流程在介绍具体的支付代码前,我们先......
  • Java项目压测 链接被拒绝
    Java项目压测-链接被拒绝在进行Java项目压测时,有时会遇到“链接被拒绝”的问题。这意味着在压测过程中,无法与目标服务器建立连接。本文将介绍一些可能导致此问题的原因,并提供相应的代码示例来解决这个问题。原因一:服务器资源不足当服务器资源不足时,无法处理大量的并发请求,会导......
  • Java图片去噪
    Java图片去噪介绍图片去噪是一种常见的图像处理技术,可以帮助我们减少图片中的噪点,提高图像的质量和清晰度。在Java中,我们可以利用一些图像处理库来实现图片去噪的功能。本文将为你介绍如何使用Java实现图片去噪的步骤和相应的代码。流程下面是实现“Java图片去噪”的流程:步......
  • Java提供三方接口对接
    Java提供三方接口对接在现代软件开发中,很常见需要与第三方服务或接口进行对接。Java作为一种跨平台的编程语言,提供了许多开箱即用的工具和库,使得与第三方接口对接变得相对简单。接口对接的基本概念在软件开发中,接口对接是指将一个系统或应用程序与另一个系统或应用程序连接在一......
  • Java数组指针
    Java数组指针在Java中,数组是一种非常常见和重要的数据结构。数组允许我们在一个变量中存储多个相同类型的元素。但是,在使用数组时,有时候我们可能需要引用数组的指针,以便更方便地操作数组的元素。本文将介绍Java中的数组指针的概念,并提供相关的代码示例。什么是数组指针?在Java中,......
  • Java数据清洗
    Java数据清洗流程步骤一:导入所需的库和类首先,我们需要导入所需的库和类。在Java中,数据清洗通常会使用到以下库和类:importjava.io.BufferedReader;//用于读取文件importjava.io.BufferedWriter;//用于写入文件importjava.io.FileReader;//用于读取文本文件importjav......
  • 7.16 动态规划
    线性DP[USACO20DEC]SleepingCowsP先不考虑极大,将奶牛和牛棚放在一起排序并离散化,设\(F_{i,j}\)为处理到第i个元素(奶牛/牛棚),有j头奶牛还没有进入牛棚的方案数。对于牛棚:\[F_{i,j}\rightarrowF_{i+1,j}\]\[j*F_{i,j}\rightarrowF_{i+1,j-1}\]对于奶牛:\[F_{i,j}......