Java SE 进阶:面向对象

零、IDEA集成开发环境

0.1 IDEA的使用

  • 在IDEA中,选择 File-New-Project 创建一个工程
  • 工程命名并为其选择工程目录,点击Finish
  • 弹出项目结构,点击上面的+号,选择New Module
  • 选择Java,点击Next,为Module命名,点击Finish,点击OK
  • 模块创建完成,在模块中的src中新建Java类

0.2 快捷键

快速生成main方法psvm或main
快速生成输出语句sout
删除一行Ctrl+Y
左侧列表移动开合方向键
新增、新建、添加的快捷键Alt+Insert
窗口变大小Ctrl+Shift+F12
切窗口Alt+左右箭头
运行Ctrl+Shift+F10
单行注释Ctrl+/
多行注释Ctrl+Shift+/
定位方法属性变量停到单词下单击Ctrl
纠正错误Alt+Enter

一、面向对象

1.1 final关键字

  • final修饰的变量不能被修改
  • final修饰的变量必须显式初始化
  • final修饰的方法不能被覆盖
  • final修饰的类不能被继承
  • 如果修饰的引用,那这个引用只能指向一个对象,不可重新赋值,但是被指向的对象可以修改
  • 构造方法不能被final修饰

1.1.1 final修饰的(基本数据类型)变量不能被修改

实例:

public class Test {
    public static void main(String[] args) {
        final int k = 10;
        k = 20;
    }
}

运行结果:

java: 无法为最终变量k分配值

1.1.2 final修饰的实例变量

  • 被final修饰的实例变量必须手动赋值,不会自动赋默认值
  • 在构造方法里赋值也行,setter方法不可行

实例:

public class Test {
    public static void main(String[] args) {

    }
}
class Person{
    final int age = 0;//手动赋值
    final boolean sex;//被final修饰的实例变量必须手动赋值,系统不会自动赋默认值
    public Person(){
		this.sex = true;//手动赋值
	}
    public Person(boolean b){
		this.sex = b;//手动赋值
	}
}
  • 实例变量被final关键字修饰后,一般会加static变为静态
  • static final修饰的变量称为常量,常量不可更改,一般为公开的

实例:

public class Test {
    public static void main(String[] args) {

    }
}
class Chinese{
    String idCard;
    String name;
    static final String COUNTRY = "中国";
}

1.1.3 final修饰的引用变量不能被修改

  • final修饰的引用变量不能被修改,但引用内部的数据是可以被修改的

实例:

public class Test {
    public static void main(String[] args) {
        final Person p = new Person(30);//该引用只能指向一个对象,并且永远只指向这个对象
        p = new Person(30);//p引用保存的地址是不可修改的
        System.out.println(p.age);
        p.age = 40;//引用内部的数据是可以被修改的
        System.out.println(p.age);
    }
}
class Person{
    int age;

    public Person() {
    }
    public Person(int age) {
        this.age = age;
    }
}

运行结果:

java: 无法为最终变量p分配值

1.1.4 final关键字修饰的类不能被继承

实例:

public class Test {
    public static void main(String[] args) {

    }
}
final class A{

}
class B extends A{

}

运行结果:

java: 无法从最终A进行继承

1.1.5 final修饰的方法不能被覆盖重写

实例:

public class Test {
    public static void main(String[] args) {

    }
}
class A{
    public final void doSome(){

    }
}
class B extends A{
    public  void doSome(){

    }
}

运行结果:

java: B中的doSome()无法覆盖A中的doSome()
  被覆盖的方法为final

1.2 抽象类

抽象类是类和类之间有共同特征再抽象成抽象类

  • 在Java中采用abstract定义的类就是抽象类,采用abstract定义的方法就叫抽象方法
  • 抽象类属于引用数据类型
  • 抽象方法只能存在于抽象类中
  • 抽象父类中有抽象方法,继承的子类要么也为抽象类,要么在子类中覆盖抽象方法
  • 抽象类无法实例化,无法创建对象
  • 抽象类也有构造方法,供子类使用
  • 抽象类不能用final修饰,抽象类就是用来被继承的
  • 抽象方法不能被final修饰,抽象方法就是用来被子类实现的
  • 向上转型多态编译时,会绑定父类中的方法,在执行时会执行子类的。

1.2.1 采用abstract定义抽象类

抽象类定义的语法格式:

[修饰符列表] abstract class 类名{
	类体;
}

1.2.2 抽象方法

抽象方法是没有实现、没有方法体的方法

例如:

public abstract void doSome();

实例:

public class Test {
    public static void main(String[] args) {
        A a = new A();//报错,抽象类无法实例化
        B b = new B();//非抽象子类可以实例化
    }
}
abstract class A{
    public abstract void doSome();
    public void doOther(){//抽象类中可以存在非抽象方法

    }
}
class B extends A{
    public void doSome(){//抽象方法在非抽象子类中必须重写

    }
}
abstract class C extends A{//在抽象子类中不需要重写父类抽象方法
}

1.3 接口

1.3.1 接口的基础语法

  • 接口也是一种引用数据类型,接口编译后也是.class字节码文件
  • 接口是完全抽象的(抽象类是半抽象)
  • 接口是可以继承的,并且支持多继承
  • 接口中只能包含常量和抽象方法(没有构造方法)
  • 接口中所有元素都是公开的,public可以省略
  • 接口中抽象方法默认都是public abstract,可以省略
  • 接口中变量都是public static final,可以省略,必须显式初始化
  • 一个非抽象的类,实现接口时,必须将接口中所有方法实现
  • 一个类可以实现多个接口
  • extends和implements同时出现时,必须extends写在前,implements写在后
  • 使用接口时,可以使用多态(父类型引用指向子类型对象)

定义接口的语法格式:

[修饰符列表] interface 接口名{

}

实例:

public class Test {
    public static void main(String[] args) {

    }
}
interface A{

}
interface B extends A{

}
interface C extends A,B{

}
interface MyMath{

    //public static final double PI=3.12;
    double PI=3.12;
    //public abstract int sum(int a,int b);
    int sum(int a,int b);
}
  • 接口可以看作是类,类之间叫继承,类和接口之间叫实现通过implements关键字完成
  • 当一个非抽象的类实现接口时,必须将接口中的所有抽象方法全部实现(覆盖重写)
  • 子类的方法访问权限要更低(封闭)才行

实例:

public class Test {
    public static void main(String[] args) {

    }
}

interface MyMath{
    double PI=3.12;
    int sum(int a,int b);
    int sub(int a,int b);
}
class MyMathImp implements MyMath{//重写的方法访问权限必须更封闭
	public int sum(int a,int b){
	return a+b;
	}    
	public int sub(int a,int b){
		return a-b;
	}    
}
//abstract class MyMathImp implements MyMath{

//}

接口和多态联合使用

实例:

public class Test {
    public static void main(String[] args) {
        MyMath mm = new MyMathImp();
        System.out.println(mm.sum(30,10));
        System.out.println(mm.sub(30,10));
    }
}

interface MyMath{
    double PI=3.14;
    int sum(int a,int b);
    int sub(int a,int b);
}
//class MyMathImp implements MyMath{
//
//}
class MyMathImp implements MyMath{
    public int sum(int a,int b){
        return a+b;
    }
    public int sub(int a,int b){
        return a-b;
    }
}

运行结果:

40
20
  • 一个类可以实现多个接口,弥补了类不能多继承的缺点

  • 接口之间在强制类型转换时,没有继承关系也可以强转。但是运行时可能会出现ClassCastException异常(假装当没讲,容易混淆没啥用)

实例:

public class Test {
    public static void main(String[] args) {
		A a = new D();
		B b = new D();
		C c = new D();
		
		B b2 = (B)a;//A和B之间没有继承关系
		b2.b();
    }
}

interface A{
    void a();
}
interface B{
    void b();
}
interface C{
    void c();
}
class D implements A,B,C{
    public void a(){

    }
    public void b(){
		System.out.println("b....");
    }
    public void c(){
 
    }
}

运行结果:

b....

实例:

public class Test {
    public static void main(String[] args) {
        B b = new C();
       if(B instanceof A){
        	A a = (A)b;//如果没有检查,就会报错
	/*Exception in thread "main" java.lang.ClassCastException: class C cannot be cast to class A (C and A are in unnamed module of loader 'app')
	at Test1.main(Test1.java:4)*/
       }
       
    }
}

interface A{

}
interface B{

}
class C implements B{

}
  • extends和implements同时出现,extends写在前,implements写在后
  • 接口通常提取的是行为动作

实例:

public class Test {
    public static void main(String[] args) {
       Flyable f = new Cat();
       f.fly();
    }
}
class Animal{

}
interface Flyable{
    void fly();
}
class Cat extends Animal  implements Flyable{
    public void fly(){
        System.out.println("飞猫起飞!");
    }
}

运行结果:

飞猫起飞!

1.3.2 接口在开发中的作用

接口在开发中的作用,类似多态在开发中的作用

实例:

public interface FoodMenu {
    void xiHongShijiDan();
    void yuXiangRouSi();
}
public class Customer {
    //凡是可以用has a形容的,统一用属性的方式存在
    //顾客有一个菜单
    private FoodMenu foodMenu;

    public Customer() {
    }
    public Customer(FoodMenu foodMenu) {
        this.foodMenu = foodMenu;
    }

    public FoodMenu getFoodMenu() {
        return foodMenu;
    }

    public void setFoodMenu(FoodMenu foodMenu) {
        this.foodMenu = foodMenu;
    }
    public void order(){
        //FoodMenu fm = this.getFoodMenu();
        foodMenu.xiHongShijiDan();
        foodMenu.yuXiangRouSi();

    }
}
public class ChinaCooker implements FoodMenu{

    public void xiHongShijiDan() {
        System.out.println("西红柿鸡蛋中国味道");
    }
    public void yuXiangRouSi() {
        System.out.println("鱼香肉丝中国味道");
    }
}
public class AmericaCooker implements FoodMenu{
    public void xiHongShijiDan() {
        System.out.println("西红柿鸡蛋美国味道");
    }
    public void yuXiangRouSi() {
        System.out.println("西红柿鸡蛋美国味道");
    }
}
public class Restaurant {
    public static void main(String[] args) {
        FoodMenu cooker1 = new ChinaCooker();
        Customer c1 = new Customer(cooker1);
        c1.order();
    }

}

运行结果:

西红柿鸡蛋中国味道
鱼香肉丝中国味道

1.3.3 类和类之间的关系

is a、has a、 like a

  • is a:Cat is a Animal 表示继承关系
    凡是满足is a的表示继承关系
  • has a:I has a Pen表示关联关系
    关联关系通常以属性形式存在
  • like a:Cooker like a FoodMenu表示实现关系
    实现关系通常是类实现接口

1.3.4 抽象类和接口的区别

  • 抽象类是半抽象的,接口是完全抽象的
  • 抽象类有构造方法,接口没有构造方法
  • 接口之间支持多继承,类之间只有单继承
  • 一个类可以实现多接口,一个抽象类只能继承一个类
  • 接口中只能出现常量和抽象方法
  • 一般接口使用的比较多,接口一般是对行为的抽象

1.4 包机制

  • package是Java包机制。是为了方便程序的管理,不同功能的类分别存放在不同的包下
  • package是一个关键字,后面加包名。例如:package com.baidu.javase.chapter17
  • package只允许出现在Java源代码的第一行(注释行不算)
  • 包名一般采用公司域名倒序的方式
    • 包名命名规范:公司域名倒序+项目名+模块名+功能名

package的Java程序编译和运行:

//在chapter17目录下的HelloWorld.java文件
package com.baidu.javase.chapter17;
//此时类名已变为com.baidu.javase.chapter17.HelloWorld
public static void main(String[] args){
    System.out.println("Hello World!");
}

在CMD中编译:

javac -d . HelloWorld.java

javac负责编译
-d带包编译
. 代表编译之后生成的东西放在当前目录下
HelloWorld.java 被编译的java文件名

在CMD中运行:

java com.baidu.javase.chapter17.HelloWorld

1.4.1 使用包机制

  • 如果两个程序在同一package下,包名可以省略。不在同一包名下,必须写全包名

实例:

package com.baidu.javase.chapter17;
public class Test1{
	public static void main(String[] args){
		com.baidu.javase.chapter17.HelloWorld hw = new com.baidu.javase.chapter17.HelloWorld();
		HelloWorld hw2 = new HelloWorld();//同一包名下,可以省略包名
	}
}
package com;
public class Test2{
	public static void main(String[] args){
		//Test1在com.baidu.javase.chapter17包下,Test2在com包下,不能省略包名
		com.baidu.javase.chapter17.HelloWorld hw = new com.baidu.javase.chapter17.HelloWorld();
		
	}
}

1.4.2 使用import机制

  • import语句只能出现在package语句之下,class声明语句之上
  • 当两个类不在同一包时,使用import。在同一包内,不需要使用
  • lang包下的东西都不需要手动导,程序自动导

实例:

package com;
import com.baidu.javase.chapter17.HelloWorld;//将需要的类导入
public class Test3{
	public static void mian(String[] args){
		HelloWorld hw = new HelloWorld();
	}
}
package com.baidu.javase.chapter17;

public class Test4{
	public static void mian(String[] args){
		java.util.Scanner s = new java.util.Scanner(System.in);//必须写明包
	}
}
package com.baidu.javase.chapter17;
import java.util.Scanner;
public class Test5{
	public static void mian(String[] args){
		//此类和Scanner类不在同一个包
		java.util.Scanner s = new java.util.Scanner(System.in);//必须写明包
	}
}

在Test5中也可以写为:

import java.util.*;//*在此只能代表某些类的名字

此种写法运行速度不会比以上写法慢

1.5访问权限控制符

  • private 私有
  • protected 受保护
  • public 公开

1.5.1 访问控制修饰符的控制范围

  • private 只能在本类中访问
  • protected 只能在本类,同包,子类中访问
  • public 在任何位置都能访问
  • 默认 只能在本类和同包下访问
    范围由大到小:public > protected > 默认 > private

1.5.2 访问控制修饰符修饰的对象

  • 属性(4个都能用)
  • 方法(4个都能用)
  • 类(public和默认可以)
  • 接口(public和默认可以)

1.6 Object类

Object类中的常用方法可以查阅Java类库的帮助文档

  • API是应用程序编程接口
  • 整个JDK类库就是一个Java SE的API
  • 每一个API都会配置一个API帮助文档

目前需要掌握的Object的方法:

protected Object clone()//负责对象克隆
int hashCode()//获取对象哈希值的一个方法
boolean equals(Object obj)//判断两个对象是否相等
String toString()//将对象转换成字符串形式
protected void finalize()//垃圾回收器负责调用的方法

1.6.1 Object类的toString方法

  • toString方法可以将一个Java对象转换成字符串表示形式

实例:

public class test {
    public static void main(String[] args) {
        MyTime t1 = new MyTime(1970,1,1);
        String s1 = t1.toString();
        System.out.println(s1);
    }
}
class MyTime{
    int year;
    int month;
    int day;
    public MyTime(){

    }
    public MyTime(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

运行结果:

MyTime@49e4cb85

但是我们并不期待这样的结果,我们期待的是具体的日期结果,所以最好重写toString()方法。

  • 建议所有子类都重写toString()方法

实例:

public class test {
    public static void main(String[] args) {
        MyTime t1 = new MyTime(1970,1,1);
        String s1 = t1.toString();
        System.out.println(s1);
    }
}
class MyTime{
    int year;
    int month;
    int day;
    public MyTime(){

    }
    public MyTime(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
   public String toString(){
        return this.year + "年" + this.month + "月" + this.day + "日";
   }
}

运行结果:

1970年1月1日

1.6.2 Object类的equals方法

  • equals方法用来判断两个对象是否相等
  • “==”用来判断两个基本数据类型是否相等,equals用来判断两个引用数据类型是否相等
  • String类重写了equals方法
  • String类重写了toString方法

equals方法的源代码:

public boolean equals(Object obj){
	return (this == obj);//源代码中用的“==”
}

实例:

public class test  {
    public static void main(String[] args) {
        MyTime t1 = new MyTime(1970,1,1);
        MyTime t2 = new MyTime(1970,1,1);
        //判断两个Java对象不能使用“==”
        System.out.println(t1==t2);//此处判断的是t1、t2中保存的对象内存地址是否相等
    }
}
class MyTime{
    int year;
    int month;
    int day;
    public MyTime(){

    }
    public MyTime(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

运行结果:

false

重写equals方法

实例:

public class test {
    public static void main(String[] args) {
        MyTime t1 = new MyTime(1970,1,1);
        MyTime t2 = new MyTime(1970,1,1);

        System.out.println(t1==t2);
        System.out.println(t1.equals(t2));
    }
}
class MyTime{
    int year;
    int month;
    int day;
    public MyTime(){

    }

    public MyTime(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public boolean equals(Object obj) {
        if(ibj == null){
			return false;
		}
        //当年月日都相等时,认为两个对象相等
        int year1 = this.year;
        int month1 = this.month;
        int day1 = this.day;
		//想要访问子类中特有的东西
		if(obj instance MyTime){
			return false;
		}
       //向下转型 强转
            MyTime mt = (MyTime) obj;
            int year2 = mt.year;
            int month2 = mt.month;
            int day2 = mt.day;
            if(this.year == year2&&this.month == month2&&this.day == day2){
                return true;
            }
            return false;
       
    }
}

运行结果:

false
true

比较两个字符串必须用equals方法

实例:

public class test {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hello";
        String s3 = new String("Hello");
        String s4 = new String("Hello");
        System.out.println(s1==s2);
        System.out.println(s1.equals(s2));
        System.out.println(s3==s4);
        System.out.println(s3.equals(s4));
    }
}

运行结果:

true
true
false
true

String类重写了toString()方法

实例:

public class test {
    public static void main(String[] args) {
        String x = new String("Hello");
        System.out.println(x);//引用数据类型当不写toString方法时,自动调用toString方法
        System.out.println(x.toString());//如果没重写toString,结果应为String@十六进制的地址
    }
}

运行结果:

Hello
Hello

实例:

public class test {
    public static void main(String[] args) {
        Student s1 = new Student(111,"北京");
        Student s2 = new Student(112,"北京");
        System.out.println(s1 == s2);//false
        System.out.println(s1.equals(s2));//true

//        Student s3 = new Student(111,new String("北京"));
//        Student s4 = new Student(112,new String("北京"));//两个北京的内存地址不同,如果用equals比较那两者通用
//        System.out.println(s3 == s4);//false
//        System.out.println(s3.equals(s4));//false
    }
}
class Student{
    int no;
    String school;
    public Student() {
    }

    public Student(int no, String school) {
        this.no = no;
        this.school = school;
    }

    public String toString() {
        return "学号"+no+"学校名称"+school;
    }
    public boolean equals(Object obj) {
        if(obj == null||!(obj instanceof Student)) return false;
        if(this == obj) return true;
        Student s = (Student) obj;
        return this.no == s.no && this.school.equals(s.school);
        //return this.no == s.no && this.school == s.school);//不可以
    }
}

运行结果:

false
false

equals方法的深层次理解

重写equals方法要彻底

实例:

public class test {
    public static void main(String[] args) {
        Address addr1 = new Address("北京","海淀区","111");
        User u1 = new User("张三",addr1);
        // User u1 = new User("张三", new Address("北京","海淀区","111"));
        User u2 = new User("张三", new Address("北京","海淀区","111"));
        System.out.println(u1.equals(u2));//true
    }
}
class User{
    String name;
    Address addr;
    public User() {
    }
    public User(String name, Address addr) {
        this.name = name;
        this.addr = addr;
    }
    //重写equals方法
    //当一个用户的姓名和地址都相同时,表示是同一个用户。这里判断两个User对象是否相等
    public boolean equals(Object obj) {
       if(obj == null||!(obj instanceof User)) return false;
       if(this == obj) return true;
        User u = (User)obj;
       if(this.name.equals(u.name) && this.addr.equals(u.addr)){
            return true;
       }
       return false;
    }
}
class Address{
    String city;
    String street;
    String zipcode;
    public Address() {
    }
    public Address(String city, String street, String zipcode) {
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }
    //这里不重写equals方法会导致上面的条件里addr的equals比较的是内存地址
    public boolean equals(Object obj) {
        if(obj == null||!(obj instanceof Address)) return false;
        if(this == obj) return true;
        Address a = (Address)obj;
        if(this.city.equals(a.city) && this.street.equals(a.street) && this.zipcode.equals(a.zipcode)){
            return true;
        }
        return false;
    }
}

运行结果:

true

1.6.3 Object类的finalize方法(了解即可,已过时)

  • JDK9之后已删除此方法

在Object类中的源代码:

protected void finalize() throws Throwable{}

只有一个方法体

  • 当一个对象即将被垃圾回收器回收时,会自动调用finalize()
  • finalize是一个垃圾销毁时机,如果希望在对象即将被销毁时执行一段代码,这段代码写在finalize方法中

实例:

public class test {
    public static void main(String[] args) {
     for (int i=0;i<1000000;i++){
         Person p = new Person();
         //将p变成垃圾
         p = null;
     }
    }
}
class Person{
    //重写finalize方法
    //Person类的对象被垃圾回收器回收时,垃圾回收器负责调用p.finalize();
    protected void finalize() throws Throwable {
        System.out.println("即将被销毁");
    }
}
  • 垃圾回收器不是轻易启动的,垃圾太少或者时机未到等条件下可能启动可能不启动
system.gc();//建议gc启动,可能听,也可能不听,仅仅是概率大一些

1.6.4 Object类的hashCode方法

hashCode的源代码:

public native int hashCode();
  • hashCode()方法带有native关键字,底层调用了C++程序
  • hashCode()方法返回的是哈希码:实际上就是一个内存地址,经过哈希算法得到一个值

实例:

public class test {
    public static void main(String[] args) {
        Object o = new Object();
        int hashCode = o.hashCode();
        System.out.println(hashCode);
    }
}

运行结果:

2083562754

1.7 匿名内部类

  • 内部类:在类的内部又定义了一个新的类
  • 内部类分为:静态内部类、实例内部类、局部内部类

实例:

class Test{
    static class Inner1{//静态内部类
        
    }
    class Inner2{//实例内部类

    }
    public void doSome(){
        int i = 100;//局部变量
        class Inner3{//局部内部类
			
		}
    }
    public void doOther(){
		//doSome()中的局部内部类Inner3,在doOther()中不能用
    }
}
  • 匿名内部类是局部内部类的一种,没有类名

未使用匿名内部类

实例:

public class Test {
    public static void main(String[] args) {
        MyMath mm = new MyMath();
        mm.MySum(new ComputerImp(),100,200);
    }
}
interface Computer{
    //抽象方法
    int sum(int a,int b);
}
class ComputerImp implements Computer{//接口的实现类
    public int sum(int a, int b) {
        return a + b;
    }
}
class MyMath{
    public void MySum(Computer c,int a,int b){
        int retValue = c.sum(a,b);
        System.out.println(a+"+"+b+"="+retValue);
    }
}

使用匿名内部类,可以不写接口的实现类

实例:

public class Test {
    public static void main(String[] args) {
        MyMath mm = new MyMath();
        mm.MySum(new Computer(){
            public int sum(int a,int b){
                return a + b;
            }
        },100,200);
    }
}
interface Computer{
    //抽象方法
    int sum(int a,int b);
}
class MyMath{
    public void MySum(Computer c,int a,int b){
        int retValue = c.sum(a,b);
        System.out.println(a+"+"+b+"="+retValue);
    }
}

}
public void doOther(){
//doSome()中的局部内部类Inner3,在doOther()中不能用
}
}


- 匿名内部类是局部内部类的一种,没有类名

未使用匿名内部类

实例:

```java
public class Test {
    public static void main(String[] args) {
        MyMath mm = new MyMath();
        mm.MySum(new ComputerImp(),100,200);
    }
}
interface Computer{
    //抽象方法
    int sum(int a,int b);
}
class ComputerImp implements Computer{//接口的实现类
    public int sum(int a, int b) {
        return a + b;
    }
}
class MyMath{
    public void MySum(Computer c,int a,int b){
        int retValue = c.sum(a,b);
        System.out.println(a+"+"+b+"="+retValue);
    }
}

使用匿名内部类,可以不写接口的实现类

实例:

public class Test {
    public static void main(String[] args) {
        MyMath mm = new MyMath();
        mm.MySum(new Computer(){
            public int sum(int a,int b){
                return a + b;
            }
        },100,200);
    }
}
interface Computer{
    //抽象方法
    int sum(int a,int b);
}
class MyMath{
    public void MySum(Computer c,int a,int b){
        int retValue = c.sum(a,b);
        System.out.println(a+"+"+b+"="+retValue);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Spring伦儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值