(Datawhale)Java Task04:面向对象编程基础


# 类与方法

面向对象概述

  • 面向机器语言

    计算机处理信息的早期语言是所谓的机器语言,使用机器语言进行程序设计需要面向机器来编写代码,即需要针对不同的机器编写诸如0101 1100这样的指令序列。

  • 面向过程语言

    随着计算机硬件功能的提高,在20世纪60年代出现了面向过程设计语言,如C语言等。用这些语言编程也称为面向过程编程。语言把代码组成叫做过程或函数的块。每个块的目标是完成某个任务。使用这些语言编写代码指令时,不必再去考虑机器指令的细节,只要按着具体语言的语法要求去编写“源文件”。

  • 面向对象语言
    基于对象的编程更加符合人的思维模式,使得编程人员更容易编写出易维护、易扩展和易复用的程序代码,更重要的是,面向对象编程鼓励创造性的程序设计。

面向对象编程主要体现三个特性:封装性 ;继承;多态

类与对象

  • Java语言是面向对象语言,它的源程序是由若干个类组成,源文件是扩展名为 .java 的文本文件。
  • 类是Java语言中最重要的“数据类型”,类声明的变量被称作对象,即类是用来创建对象的模板。
  • 类的实现包括两部分:类声明和类体。基本格式为:
class 类名 {
   //类的成员变量
   //类的成员方法
   //类体的内容等
}

成员变量

在 Java 中对象的属性也称为成员变量,成员变量的定义与普通变量的定义一样,语法如下:

数据类型 变量名称[=值]

其中,[=值]表示可选内容,定义变量时可以为其赋值,也可以不为其赋值。如果不设置初始值,则会有默认值。

类及其成员变量的定义示例:

public class Bird{
	String wing;  //翅膀
	String claw;  //爪子
	String beal;  //喙
	String feather;  //羽毛
}

成员方法

  1. 成员方法的定义,语法格式如下:
 [权限修饰符] [返回值类型]方法名([参数类型 参数名])[throws 异常类型]{
	//方法体
	return 返回值;
}
  • 权限修饰符可以是 private、public,protected中的任意一个,也可以不写,主要用来控制方法的访问权限;

  • 返回值类型用来指定方法返回数据的类型,可以是任何类型,如果方法不需要返回值,则使用void关键字;

  • 一个成员方法既可以有参数,也可以没有参数,参数可以是对象,也可以是基本数据类型的变量。

  • 注∶方法的定义必须在某个类中,定义方法时如果没有指定权限修饰符,方法的默认访问权限为缺省(即只能在本类及同一个包中的类中进行访问)。

    1. 成员方法的参数

调用方法时可以给该方法传递一个或多个值,传给方法的值叫作实参,在方法内部,接收实参的变量叫作形参,形参的声明语法与变量的声明语法一样。形参只在方法内部有效

Java中方法的参数主要有3 种,分别为值参数、引用参数和不定长参数:

  • 值参数

    值参数表明实参与形参之间按值传递,当使用值参数的方法被调用时,编译器为形参分配存储单元,然后将对应的实参的值复制到形参中,由于是值类型的传递方式,所以,在方法中对值类型的形参的修改并不会影响实参。

  • 引用参数

    如果在给方法传递参数时,参数的类型是数组或者其他引用类型,那么,在方法中对参数的修改会反映到原有的数组或者其他引用类型上,这种类型的方法参数被称之为引用参数。

  • 不定长参数

    声明方法时,如果有若干个相同类型的参数,可以定义为不定长参数,该类型的参数声明为∶权限修饰符 返回值类型 方法名(参数类型... 参数名),其中参数类型和参数名之间是三个点,而不是其他数量或省略号。

构造方法

在类中除了成员方法之外,还存在一种特殊类型的方法,那就是构造方法。**构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。**每当类实例化一个对象时,类都会自动调用构造方法。
构造方法的特点如下∶

  • 构造方法没有返回类型,也不能定义为void;
  • 构造方法的名称要与本类的名称相同;
  • 构造方法的主要作用是完成对象的初始化工作,它能把定义对象的参数传给对象成员

构造方法的定义语句代码如下:

class Book{
	public Book(){  //(无参)构造方法
	}
}

在构造方法中可以为成员变量赋值,这样当实例化一个本类的对象时,相应的成员变量也将被初始化。如果类中没有明确定义构造方法,则编译器会自动创建一个不带参数的默认构造方法。

除此之外,在类中定义构造方法时,还可以为其添加一个或者多个参数,即有参构造方法,语法如下:

class Book {
	public Book(int args){  //有参构造方法
		//对成员变量进行初始化
	}
}

this关键字

如果方法中出现了与局部变量同名的参数,会导致方法无法直接使用成员变量。

Java语言中规定使用this关键字来代表本类对象的引用,this关键字被隐式地用于引用对象的成员变量和方法。此外,它还可以调用类中的构造方法。

实例

创建一个借书类BorowABook,借书类中有书名属性name,参数为name的构造方法和借书方法borrow()。编写一个程序,使用this关键字调用书名属性后,借阅《战争与和平》这本书。代码如下∶

public class BorrowABook { // 创建借书类
	String name; // 属性:书名
	public BorrowABook(String name) { // 参数为name的构造方法
		this.name = name; // 将参数name的值付给属性name
	}
	public void borrow() { // 借书方法
		System.out.println("请前往借阅登记处领取" + name + "。"); // 输出借出的书名
	}
	public static void main(String[] args) {
		// 创建参数为“《战争与和平》”的借书类对象,
		BorrowABook book = new BorrowABook("《战争与和平》");
		book.borrow(); // 调用借书方法
	}
}

  • this关键字虽然可以调用成员变量和成员方法,但Java语言中最常规的调用方式是使用"对象.成员变量"或"对象.成员方法"进行调用;
  • this关键字除了可以调用成员变量或成员方法之外,还可以作为方法的返回值。
例如,在项目中创建一个类文件,在该类中定义Book类型的方法,并通过过this关键字进行返回。
public class Book{
	public getBook(){
		return this;  //返回Book类引用
	}
}

getBook()方法中,方法的返回值为Book类,所以方法体中使用return this这种形式将Book类的对象进行返回。

static 关键字

由static修饰的变量、常量和方法分别被称作静态变量、静态常量和静态方法,也被称作类的静态成员。

静态变量

很多时候,不同的类之间需要对同一个变量进行操作。在Java程序中,如果把共享的变量用static修饰,那么该变量就是静态变量。
调用静态变量的语法如下∶

类名.静态类成员

静态方法

如果想要使用类中的成员方法,需要先将这个类进行实例化,但有些时候不想或者无法创建类的对象时,还要调用类中的方法才能够完成业务逻辑,这种情况下就可以使用静态方法。
调用类的静态方法语法如下∶

类名.静态方法();

实例

创建一个水池类,使用静态变量表示水池中的水量,并初始化水池中的水量为0,通过注水方法(一次注入3个单位)和放水方法(一次放出2个单位),控制水池中的水量。代码如下∶


public class Pool { // 创建水池类
	public static int water = 0; // 初始化静态变量之水池中的水量为0
	public static void outlet() { // 放水,一次放出2个单位
		if (water >= 2) { // 如果水池中的水量大于等于2个单位
			water = water - 2; // 放出2个单位的水
		} else { // 如果水池中的水量小于2个单位
			water = 0; // 水池中的水量为0
		}
	}
	public static void inlet() { // 注水,一次注入3个单位
		water = water + 3; // 注入3个单位的水
	}
	public static void main(String[] args) {
		System.out.println("水池的水量:" + Pool.water); // 输出水池当前水量
		System.out.println("水池注水两次。");
		Pool.inlet(); // 调用静态的注水方法
		Pool.inlet(); // 调用静态的注水方法
		System.out.println("水池的水量:" + Pool.water); // 输出水池当前水量
		System.out.println("水池放水一次。");
		Pool.outlet(); // 调用静态的放水方法
		System.out.println("水池的水量:" + Pool.water); // 输出水池当前水量
	}
}


静态代码块

在类的成员方法之外,用static修饰代码区域可以称之为静态代码块。定义一块静态代码块,可以完成类的初始化操作,在类声明时就会运行。
语法如下∶

public class StaticTest {
 	static {
 	// 此处编辑执行语句
 	}
}

实例**
创建静态代码块、非静态代码块、构造方法、成员方法,查看这几处代码的调用顺序。代码如下:

public class StaticTest {
	static String name;
	// 静态代码块
	static {
		System.out.println(name + "静态代码块");
	}
	// 非静态代码块
	{
		System.out.println(name + "非静态代码块");
	}
	public StaticTest(String a) {
		name = a;
		System.out.println(name + "构造方法");
	}
	public void method() {
		System.out.println(name + "成员方法");
	}
	public static void main(String[] args) {
		StaticTest s1;// 声明的时候就已经运行静态代码块了
		StaticTest s2 = new StaticTest("s2");// new的时候才会运行构造方法
		StaticTest s3 = new StaticTest("s3");
		s3.method();// 只有调用的时候才会运行
	}
}

类的主方法

主方法是类的入口点,它指定了程序从何处开始,提供对程序流向的控制。Java编译器通过主方法来执行程序。主方法的语法如下∶

public static void main(String[] args){
		// 方法体
}
  • 主方法是静态的,所以如要直接在主方法中调用其他方法,则该方法必须也是静态的;
  • 主方法没有返回值;
  • 主方法的形参为数组,其中args[0]~args[n]分别代表程序的第一个参数到第n+1个参数,可以使用 args.length获取参数的个数。

继承与多态

继承

继承是面向对象编程中的特征之一,即从已有的类中派生出新的类,新的类具有父类的方法,同时也可以增加新的方法。这种特性使得复用代码非常容易,缩短开发周期。

在java中使用extends 关键字来声明子类继承于某父类,如下:

class 父类 {
}
 
class 子类 extends 父类 {
}

实例

  • 公共父类
public class Animal { 
    private String name;  
    private int id; 
    public Animal(String myName) { 
        name = myName; 
    } 
    public void eat(){ 
        System.out.println(name+"正在吃"); 
    }
    public void sleep(){
        System.out.println(name+"正在睡");
    }
    public void introduction() { 
        System.out.println("我是" + name + "."); 
    } 
}
  • 老虎类
public class tiger extends Animal { 
    public Penguin(String myName) { 
        super(myName); 
    } 
}
  • 兔子类
public class rabbit extends Animal { 
    public Mouse(String myName) { 
        super(myName); 
    } 
}

继承类型

继承分单继承和多重继承,Java不支持多继承。

单继承和多重继承:单继承是指一个子类最多只能有一个父类;多继承是一个子类可以有二个以上的父类。

多重继承例子如下:

public class A{}
public class B extends A{}
public class C extends B{}

继承关键字

implements

Java除了extends,还可以用implements关键字来实现继承。Java中不支持多重继承,但是用implements可以实现多个接口,相当于使得Java具有多继承的特性。

public interface if1 {
    public void method1();
}
 
public interface if2 {
    public void method2();
}
 
public class if3 implements if1,if2 {
}

super与this

super:引用当前对象的父类成员

this:指向当前类的引用。

class Father {
  void method() {
    System.out.println("这是父类的方法");
  }
}
 
class Son extends Father {
  void method() {
    System.out.println("这是子类的方法");
  }
  void diff_method() {
    this.method();   
    super.method();  
  }
}
 
public class Test {
  public static void main(String[] args) {
    Father father = new Father();
    father.method();
    Son son = new Son();
    son.diff_method();
  }
}

final

final的功能是将类定义为不可继承的,也可以用于修饰方法,被修饰的方法不可被子类重写。

继承的特性

  1. 子类不继承父类的private属性和方法;
  2. 子类可以对父类进行扩展,拥有自己的属性和方法;
  3. 子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过super关键字调用父类的构造器并配以适当的参数列表;
  4. 如果父类构造器没有参数,则在子类的构造器中不需要使用super关键字调用父类构造器,系统会自动调用父类的无参构造器。

多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态的转型

多态的转型有向上转型和向下转型两种。

  • 向上转型

    当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作:父类类型 变量名=new 子类类型()

  • 向下转型

    当要使用子类特有功能时:子类类型 变量名=(子类类型) 父类类型的变量;

实例

public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 对象调用 show 方法,向上转型 Animal a = new Cat()
      show(new Dog());  // 以 Dog 对象调用 show 方法,向上转型 Animal a = new Dog()
                
      // Animal a = new Cat();  // 向上转型  
      // a.eat();               // 调用的是 Cat 的 eat
      // Cat c = (Cat)a;        // 向下转型  
      // c.work();        // 调用的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
      a.eat();  
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}

参考资料

  1. DataWhale Java组队学习
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值