java面向对象3

本文介绍了Java编程中的面向过程和面向对象概念,比较了两者在处理长方形面积和周长计算上的差异,讨论了抽象类的定义、抽象方法的实现、继承、static和final关键字的使用,以及对象数组和二维数组的初始化和操作。
摘要由CSDN通过智能技术生成

1.面向过程&面向对象

1.1面向过程

// 计算三个长方形的面积和周长
// *** 面向过程编程
public class Home1 {
public static void main(String[] args) {
      // 第一个
      double w1 = 10;
      double h1 = 10;
      System.out.println("①周长:" + (w1+ h1)*2);
      System.out.println("①面积:" + (w1*h1));
      // 第二个
      double w2 = 4;
      double h2 = 5;
      System.out.println("②周长:" + (w2+ h2)*2);
      System.out.println("②面积:" + (w2*h2));
      // 第三个
      double w3 = 4;
      double h3 = 5;
      System.out.println("③周长:" + (w3+ h3)*2);
      System.out.println("③面积:" + (w3*h3));
      // 第n个(重复上面的代码)
   }
}

1.2面向对象

// 计算三个长方形的面积和周长
// 面向对象: 封装一个长方形类(特征: w , h , 功能: 计算周长, 计算面积) , 然后创建对象, 调用对象的属性和方法。
public class Home2 {
   public static void main(String[] args) {
      Rect r1 = new Rect(10,10);
      System.out.println("矩形1周长:" + r1.grith() );
      System.out.println("矩形1面积:" + r1.area());
      Rect r2 = new Rect(3,4);
      System.out.println("矩形2周长:" + r2.grith() );
      System.out.println("矩形2面积:" + r2.area());
   }
}
class Rect{
   double w;
   double h;

   public Rect(){}
   public Rect(int w ,int h){
      this.w = w;
      this.h =h;
   }
   public double grith(){
      return 2* (w+h);
   }
   public double area(){
      return w*h;
   }
}

对比

// 表示一个学生
public class Home3 {
   public static void main(String[] args) {
      String name = "alice";
      String sex = "女生";
      int age = 22;
      String hobby = "看书";
      System.out.println(name +"--" + sex +"---" + age +"---" + hobby +"----");
      System.out.println("-----------------------");
      Student stu = new Student();
      stu.intro();
   }
}
class Student{
   String name;
   String sex ;
   int age ;
   String hobby ;
   public void intro(){
   System.out.println(name +"--" + sex +"---" + age +"---" + hobby +"---- ");
   }
}

2.方法的定义—return关键字

  • 如果方法定义中有返回值类型的设置,需要使用return返回一个相同类型的数据
class Rect{
   double w;
   double h;
   public Rect(){}
   public Rect(double w, double h){
      this.w = w;
      this.h = h;
   }
   public double girth(){
      return 2 * (w + h);
   }
   public double area(){
      return w * h;
   }
}
  • 在方法中,可以使用return关键字,结束方法的运行

3.static关键字的使用

3.1static 关键字—修饰成员变量

  • 用static修饰的成员变量不属于对象的数据结构

  • static修饰的变量属于类的变量,通常可以通过类名来引用static成员

  • static成员变量和类的信息一起存储在方法区,而不是在堆内存中

  • 一个类的静态成员变量只有一份,而非静态成员对象有多份,即每个对象都有自己的非静态成员变
    量。

  public class Cat {
     //猫的特征(描述对象)
     String name;
     String sex;
     int age;
     // 统计出猫(对象)的个数
     static int count;

     public Cat() {
        count++;
     }
      
     public Cat(String name, String sex, int age){
        this.name = name;
        this.sex = sex;
        this.age = age;
        count++;
     }

  }
  class TestCat {
     public static void main(String[] args) {
        //count 是Cat类中的静态变量,可以通过类名直接访问静态变量
        System.out.println(Cat.count);  // 0
        Cat cat = new Cat();
        cat.age = 3;
        cat.sex = "公猫";
        cat.name = "tom";
        //cat.count++;
        //Cat.count++;  // 增加了一只猫
        //System.out.println(cat.count);  // 1
        System.out.println(Cat.count);

        Cat c1 = new Cat();
        c1.age = 2;
        c1.sex = "公猫";
        c1.name = "jerry";
        //cat.count++;
        //Cat.count++;
        System.out.println(Cat.count);
     }
  }

3.2static关键字—修饰方法

  • 类中的方法,通常都会涉及到堆具体对象的操作,这些方法在调用时,需要隐式的传递对象的引

    用。

    ​ void print(){

    ​ System.out.println(this.x + “,” + this.y);

    ​ }

  • static修饰的方法则不需要针对对象进行操作,其运行结构仅仅与输入的参数有关系。调用时候直

    接通过类名引用。

    ​ Math.sqrt(100)

  • static修饰的方法是属于类的方法,通常用于提供工厂方法,或者工具方法。

  • static修饰的方法,调用的时候没有具体的对象,因此static修饰的方法不能调用非静态成员变量和

    成员方法。

//静态方法中,无法调用非静态成员变量和非静态的成员方法
// *** 非静态成员变量和非静态的成员方法,属于对象的, 只能通过对象调用。
// *** 静态的成员变量和成员方法,属于类的,可以通过类名直接调用(也可以通过对象的引用进行调用)。
public class Dog {
   String name;
   String sex;
   static int count;

   //输出狗的数量。以及当前这只狗的属性
   public void print(){// 非静态方法: 属于对象,通过对象进行调用。
      System.out.println("一共:" + count);
      System.out.println("名字:" + this.name + ", 性别" + this.sex);
   }

   //增加狗的数量:只要new了一个对象,就调用add方法,修改狗的总数
   public static void add(){
      count++;
      /*
      System.out.println("当前增加的狗的名字:" + this.name); // 静态方法:属于类,name是非静态的成员变量,属于对象的。
      this.print();   // print() 是非静态方法,属于对象,通过对象来调用。
      */
   }

   public static void main(String[] args) {
      count++;
      add();

      //name ="xx";  // 非静态的。不能直接在静态方法中使用
      Dog dog = new Dog();
      dog.name = "tom";
      dog.sex = "公";
      dog.print();
   }
}

4.final关键字

  • 修饰类

    • ​ final关键字修饰的类不可以被继承
    • ​ 对于一些类,设置了final修饰,可以避免滥用继承造成的危害
  • 修饰方法

    • ​ final关键字修饰的方法可以不被重写

    • ​ 防止子类在定义自己的方法的时候,不经意被重写。

public class FianlDemo {
}
//final修饰的类不能被继承
//*** jdk中的很多类,都是final修饰的
final class A{}

//class B extends A{}

class Shape{
   // final修饰的变量,就不可以修改数据值。
   static final double PI = 3.14;  // static + final 修饰成员变量,本质定义的是常量。
   int x, y;
   // final修饰的方法,不允许被子类重写
   final public void print(){
      //* 常量:为了方便程序中使用常量,常量定义为 static + final修饰,常量都用大写字母表示(常量是多个单词,使用_分割)
      /*Math.PI;
      Integer.MAX_VALUE;
      Integer.MIN_VALUE;*/
      System.out.println("x: " + x+" y: " + y);
   }
}
/*
class SanJiao extends Shape{
   //父类的方法是final修饰的,子类不能被重写
   @Override
   public void print() {
      System.out.println("*****x: " + x+" y: " + y);
   }
}*/
  • 修饰变量

    • final修饰成员变量,意为不可以改变。该成员变量需要在初始化的时候赋值,对象一旦创

      建,即该值不可以改变。

public class FinalDemo1 {
   //创建数组,长度固定为5
   static final int LENGTH =5;
   // 1~100的素数
   static final int MAX = 100;
   //连接mysql数据库
   static final int PORT = 3306;

   public static void main(String[] args) {
      int[] a = new int[FinalDemo1.LENGTH];
      for (int i = 0; i <= a.length; i++){
         a[i] =i;
      }
      for (int i = 2; i <= FinalDemo1.MAX; i++){
         return ;
      }
      //使用PORT
      System.out.println(FinalDemo1.PORT);
   }
}

5.对象数组

所谓对象数组,对象数组的元素不是基本类型,而是引用类型。

image-20230728101047551

5.1对象数组的初始化和使用

对象数组的初始化和基本类型数组的初始化方式一样,只不过元素是对象引用而已。
对象数组创建之后,元素的默认值是null.

Point

class Point{
	int x;
	int y;
	public Point(){

	}
	public Point(int x, int y){
		this.x = x;
		this.y = y;
	}
	public void print(){
		System.out.println("("+x+","+y+")");
	}
	// 计算两个点之间的距离
	public double distance(Point p){
		// this是一个点,point是另一个点
		return Math.sqrt(Math.pow(this.x - p.x, 2) + Math.pow(this.y - p.y, 2));
	}
}

对象数组的使用

// 对象数组: 数组元素存储的是对象的引用地址
public class ArrayDemo {
   public static void main(String[] args) {
      Point[] ps;  // 数组(对象数组)
      ps = new Point[4];   // 表示数组的长度  --- 数组的元素默认值是null
      ps[0] = new Point(2,2);
      ps[1] = new Point(3,3);
      ps[2] = new Point(4,4);
      ps[3] = new Point(5,5);
      for(int i = 0; i < ps.length; i++) {
         ps[i].print();
      }
      Point p1 = ps[0]; //把对象的引用地址赋值给另一个引用
      p1.x = 10;
      p1.y = 10;
      System.out.println("------------------------数组元素的xy被修改了");
      for(int i = 0; i < ps.length; i++) {
         ps[i].print();
      }
      Point p2 = new Point(3,3);
      ps[1] = p2;

      System.out.println("------------------------");
      for(int i = 0; i < ps.length; i++) {
         ps[i].print();
      }

      System.out.println("------------------------");
      // 赋值
      ps[0] = ps[1] = ps[2] = ps[3];  // 4个指向同一个对象
      ps[2].x = 7;
      ps[3].y = 8;
      for(int i = 0; i < ps.length; i++) {
         ps[i].print();
      }
   }
}

5.2二维数组

数组的元素可以为任何类型,也包括数组类型
  • 数组的元素可以为任何类型,也包括数组类型。
int[][] arr = new int[3][];
arr[0] = new int[5]
arr[1] = new int[4]
arr[2] = new int[5]
  • 数组类型数组的初始化
int[][] = {{1,3,2},{4,5,6}}
Point[][] ps = {{new Point(1,2),new Point(1,2)},{new Point(1,2),new
Point(1,2)}}
如果每个数组的元素长度相同:
int[][] = new int[3][5]
  • 二维数组的使用
public class ArrayDemo2 {
    public static void main(String[] args) {
        int[][] a1 = new int[4][5];  // 数组放多少个数据?
        //给二维数组赋值
        for(int i = 0; i < a1.length; i++) {  // a1.length 是第一维的长度
            int[] datas = a1[i];
            for(int j = 0; j < datas.length; j++) {  //datas.length 是第二维的长度(5)
                datas[j] = j + i;
            }
        }

        int[][] ds = new int[10][10];
        int count = 1;
        for(int i = 0; i < ds.length; i++){
            for(int j = 0; j < ds[i].length; j++){
                ds[i][j] = count++;
            }
        }

        System.out.println("输出数组:");
        for(int i = 0; i < ds.length; i++){
            for(int j = 0; j < ds[i].length; j++){
                System.out.print(ds[i][j] + "\t");
            }
            System.out.println();
        }
    }
}
  • 对象类型的二维数组的使用
//创建一个Point类型的二维数组,然后存放Point对象的引用, 计算出两个点之间的距离
public class ArrayDemo3 {
    public static void main(String[] args) {
        Point[][] ps = new Point[5][2];   //10个点,分成5个组,每个组两个点
        //数组初始化(点的x,y使用随机数生成)
        Random rand = new Random();
        for(int i = 0; i     < ps.length; i++) {
            for(int j = 0; j < ps[i].length; j++) {
                Point p = new Point();  // 创建10个Point对象
                p.x = rand.nextInt(10);
                p.y = rand.nextInt(10);
                ps[i][j] = p;
            }
        }
        //计算
        for(int i = 0; i < ps.length; i++) {
            Point p1 = ps[i][0];
            Point p2 = ps[i][1];
            double line = p1.distance(p2);
            //System.out.println(p1.print()+"\n"+p2.print());
            System.out.println("line: " + line);
        }
    }
}

6.什么是抽象类

6.1abstract关键字

  • 用abstract关键字修饰的类称之为抽象类。

  • 抽象类不能实例化,抽象类的意义在于“被继承”。

  • 抽象类为子类“抽象”出公共部分,通常也定义了子类所必须实现的抽象方法。

// *** abstract : 抽象, java中的关键字, 在类面前,表示是抽象类,在方法面前,表示是一个抽象方法
// *** 抽象类中: 成员变量 , 成员方法 (实现了的方法,和没有实现的抽象方法)
abstract class Animal{
 int age;  // 年龄
 double hp;  // 生命值

 public Animal(){
    System.out.println("animal.......,所有动物的父类。");
 }

 public void eat(String food){
    System.out.println("吃:" + food);
 }

 //抽象方法:用abstract修饰,没有方法体
 // ** 休息的方式不同,定义一个方法,不实现这个方法,让子类自己实现。  ----规范了所有子类,必须有sleep方法
 public abstract void sleep();

 public abstract void sing();
}

6.2继承抽象类

  • 一个抽象类可以有抽象方法,也可以有非抽象方法
  • 一个类继承了抽象类,那么必须实现父类的抽象方法,除非该类依然定义为抽象类。
// ** Bird继承了抽象类,就需要实现父类的抽象方法。否则Bird依然设置为抽象类
//** Bird作为子类,继承的父类的所有抽象方法,都需要实现。如果没有具体的函数体,就空实现(解决编译错误)
public class Bird extends Animal {
   @Override
   public void sleep(){
      System.out.println("鸟在鸟窝里休息........");
   }

   @Override // 空实现: 方法体没有任何代码, 为了解决编译错误。
   public void sing() {}
   public void egg() {
      System.out.println("鸟下蛋了....");
   }
}
// ** 抽象类的子类,依然是一个抽象类,那么这个子类可以不实现父类中的抽象方法,也可以实现。
abstract class WoNiu extends Animal{  // 蜗牛类
   @Override
   public void sleep(){
      System.out.println("蜗牛在树叶上休息.........");
   }
}

class GoldWoNiu extends WoNiu{

   @Override  // 空实现
   public void sing() {

   }
   public void run() {
      System.out.println("黄金蜗牛在沙滩上爬......");
   }
}

class TestAnimal{
	public static void main(String[] args) {
		//Animal animal = new Animal();  // ----抽象类不能被实例化
		//WoNiu woNiu = new woNiu();   // ----抽象类不能被实例化
		Animal a1 = new Bird();   // 向上造型
		a1.sing();
		a1.sleep();
		//a1.egg();  //编译错误: 编译的时候,a1是Animal类型,没有egg方法。无法调用。
		// **两种转型方法
		if (a1 instanceof Bird){
			Bird b1 = (Bird)a1;  // 如果子类有某个特殊方法不能使用,那么只能强转后才能使用
		}
		if (a1.getClass() == Bird.class) {
			Bird b2 = (Bird)a1;
		}

		WoNiu ww = new GoldWoNiu();
		GoldWoNiu gwn = new GoldWoNiu();
		Animal a = new GoldWoNiu();
		//调用run方法
		gwn.run();
		if (a instanceof GoldWoNiu) {
			GoldWoNiu gg1 = (GoldWoNiu)a;
			gg1.run();
		}
		if (ww.getClass() == GoldWoNiu.class) {
			GoldWoNiu gg2 = (GoldWoNiu) ww;
			gg2.run();
		}
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

A码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值