3.4面向对象高级

1抽象类

概念
抽象类必须使用abstract class声明
一个抽象类中可以没有抽象方法。抽象方法必须写在抽象类或者接口中。
格式:
abstract class 类名{ // 抽象类
}

抽象方法

只声明而未实现的方法称为抽象方法(未实现指的是:没有“{}”方法体),抽象方法必须使用abstract关键字声明。
格式:



abstract class 类名{ // 抽象类
public abstract void 方法名() ; // 抽象方法,只声明而未实现
}`
在抽象类的使用中有几个原则:
· 抽象类本身是不能直接进行实例化操作的,即:不能直接使用关键字new完成。
· 一个抽象类必须被子类所继承,被继承的子类(如果不是抽象类)则必须覆写(重写)抽象类中的全部抽象方法

常见问题

1、 抽象类能否使用final声明?
不能,因为final属修饰的类是不能有子类的 , 而抽象类必须有子类才有意义,所以不能。
2、 抽象类能否有构造方法?
能有构造方法,而且子类对象实例化的时候的流程与普通类的继承是一样的,都是要先调用父类中的构造方法(默
认是无参的),之后再调用子类自己的构造方法。


## 抽象类和普通类的区别
1、抽象类必须用publicprotected修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法)。
默认缺省为 public
2、抽象类不可以使用new关键字创建对象, 但是在子类创建对象时, 抽象父类也会被JVM实例化。
3、如果一个子类继承抽象类,那么必须实现其所有的抽象方法。如果有未实现的抽象方法,那么子类也必须定义为abstract类


## 2、接口 概念
如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么此时就可以将这个类定义成一个接口。
定义格式:
interface 接口名称{
全局常量 ;
抽象方法 ;
}
这种思想是接口是定义(规范,约束)与实现(名实分离的原则)的分离。
优点:
1、 降低程序的耦合性
2、 易于程序的扩展
3、 有利于程序的维护

接口的实现 implements


接口可以多实现:
格式:
class 子类 implements 父接口1,父接口2...{
}
以上的代码称为接口的实现。那么如果一个类即要实现接口,又要继承抽象类的话,则按照以下的格式编写即可:
class 子类 extends 父类 implements 父接口1,父接口2...{
}

接口和抽象类的区别

1、抽象类要被子类继承,接口要被类实现。
2、接口只能声明抽象方法,抽象类中可以声明抽象方法,也可以写非抽象方法。
3、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
4、抽象类使用继承来使用, 无法多继承。 接口使用实现来使用, 可以多实现
5、抽象类中可以包含static方法 ,但是接口中不允许(静态方法不能被子类重写,因此接口中不能声明静态方法)
6、接口不能有构造方法,但是抽象类可以有

## `**

3、多态 概念

** `
多态:就是对象的多种表现形式,(多种体现形态)
类似于基本数据类型的转换:
· 向上转型:将子类实例变为父类实例
|- 格式:父类 父类对象 = 子类实例 ;
· 向下转型:将父类实例变为子类实例
|- 格式:子类 子类对象 = (子类)父类实例 ;

4instanceof

作用:
判断某个对象是否是指定类的实例,则可以使用instanceof关键字
格式:
实例化对象 instanceof//此操作返回boolean类型的数据

## 5、Object类 概念

Object类是所有类的父类(基类),如果一个类没有明确的继承某一个具体的类,则将默认继承Object类。
例如我们定义一个类:
public class Person{
}
其实它被使用时 是这样的:
public class Person extends Object{
}

使用Object可以接收任意的引用数据类型

建议重写Object中的toString方法。 此方法的作用:返回对象的字符串表示形式。
Object的toString方法, 返回对象的内存地址

equals

建议重写Object中的equals(Object obj)方法,此方法的作用:指示某个其他对象是否“等于”此对象。
Object的equals方法:实现了对象上最具区别的可能等价关系; 也就是说,对于任何非空引用值x和y ,当且仅当
x和y引用同一对象( x == y具有值true )时,此方法返回true 。
equals方法重写时的五个特性:
自反性 :对于任何非空的参考值x , x.equals(x)应该返回true 。
对称性 :对于任何非空引用值x和y , x.equals(y)应该返回true当且仅当y.equals(x)回报true 。
传递性 :对于任何非空引用值x , y和z ,如果x.equals(y)回报true个y.equals(z)回报true ,然后
x.equals(z)应该返回true 。
一致性 :对于任何非空引用值x和y ,多次调用x.equals(y)始终返回true或始终返回false ,前提是未修改对象
上的equals比较中使用的信息。
非空性 :对于任何非空的参考值x , x.equals(null)应该返回false 。

## 6、内部类
在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
广泛意义上的内部类一般来说包括这四种:
1、成员内部类
2、局部内部类
3、匿名内部类
4、静态内部类

```java
class Outer {
private double x = 0;
public Outer(double x) {
this.x = x;
}
class Inner { //内部类
public void say() {
System.out.println("x="+x);
}
}
}
特点: 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问
的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或
者该作用域内。
例如:
class Person{
public Person() {
}
}
匿名内部类
注意:
静态内部类
class Man{
public Man(){
}
public People getPerson(){
class Student extends People{ //局部内部类
int age =0;
}
return new Student();
}
}

匿名内部类由于没有名字,所以它的创建方式有点儿奇怪。创建格式如下:
new 父类构造器(参数列表)|实现接口()
{
//匿名内部类的类体部分
}
在这里我们看到使用匿名内部类我们必须要继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一
个接口。同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用。当然这个引用是隐
式的。

静态内部类

class Outter {
public Outter() {
}
static class Inner {
public Inner() {
}
}
}

7、 包装类 概述

  1. 在Java中有一个设计的原则“一切皆对象”,那么这样一来Java中的一些基本的数据类型,就完全不符合于这种设计思想,因为Java中的八种基本数据类型并不是引用数据类型,所以Java中为了解决这样的问题,引入了八种基本数据类型 的包装类
    在这里插入图片描述
    装箱和拆箱
    以下以Integer和Float为例进行操作
    将一个基本数据类型变为包装类,那么这样的操作称为装箱操作。
    将一个包装类变为一个基本数据类型,这样的操作称为拆箱操作,
    因为所有的数值型的包装类都是Number的子类,Number的类中定义了如下的操作方法,以下的全部方法都是进行拆箱的操
    作。
使用包装类还有一个很优秀的地方在于:可以将一个字符串变为指定的基本数据类型,此点一般在接收输入数据上使用
较多。
在Integer类中提供了以下的操作方法:
public static int parseInt(String s) :将String变为int型数据
在Float类中提供了以下的操作方法:
public static float parseFloat(String s) :将String变为Float
在Boolean 类中提供了以下操作方法:
public static boolean parseBoolean(String s) :将String变为boolean
...

.8、可变参数

方法中定义完了参数,则在调用的时候必须传入与其一一对应的参数,但是在JDK 1.5之后提供了新的功能,可以根
据需要自动传入任意个数的参数。
语法:
返回值类型 方法名称(数据类型…参数名称){
//参数在方法内部 , 以数组的形式来接收
}
注意:
可变参数只能出现在参数列表的最后。

9、递归
递归,在数学与计算机科学中,是指在方法的定义中使用方法自身。也就是说,递归算法是一种直接或者间接调用自身方
法的算法。

例题;

import java.util.Scanner;

public class UserServiceTest {

	public static void main(String[] args) {
      Scanner input = new Scanner(System.in);
		System.out.println("请输入账号:");
		String userName = input.next();
		System.out.println("请输入密码:");
		String passWord = input.next();
		boolean rs=new UserService().login(userName,passWord);
		System.out.println(rs==true?"登录成功":"登录失败");
	}

}

class UserService {
	private String userName = "admin";
	private String passWord = "123";
	

  public boolean login(String name,String pass) {
		
		if (this.userName.equals(name) && this.password.equals(pass)) {
			return true;
		} else {
			return false;
		}
	}
}
数组扩容

```java
package com;

public class MyList {
	private Object[] element;
	private int size;
	
	public MyList() {
		super();
		// TODO Auto-generated constructor stub
	}
	public MyList(Object[] element, int size) {
		super();
		this.element = element;
		this.size = size;
	}
	
	public void add(Object o) {
		if (size < element.length) {
			element[size] = o;
		}else {
			// 需要扩容
			Object[] element2 = new Object[2 * element.length];
			for (int i = 0; i < element.length; i++) {
				element2[i] = element[i];
			}
			element = element2;
			element[size] = o;
		}
		size++;
	}
	public void remove(Object o) {
		int flag = 0;
		int j;
		for (j = 0; j < element.length; j++) {
			if(element[j].equals(o)) {
				flag = 1;
				break;
			}
		}
		for (int k = j + 1; k < element.length; k++) {
			element[k - 1] = element[k];
		}
		if (flag == 1) {
			size--;
		}else {
			System.out.println("无效的数据,未能删除任何数据");
		}
	}
	
	public void remove(int i) {
		if (i <= size - 1) {
			for (int k = i + 1; k < element.length; k++) {
				element[k - 1] = element[k];
			}
			size--;
		}
		else {
			System.out.println("无效的下标,未能删除任何数据");
		}
	}
	
	public Object get(int i) {
		for (int j = 0; j < element.length; j++) {
			if(j == i) {
				return this.element[j];
			}
		}
		System.out.println("查无此项,返回值为null");
		return null;
	}
	
	public int getListLength() {
		return element.length;
	}
	
	public void printList() {
		for (int i = 0; i < size; i++){
			System.out.print(element[i] + " ");
		}
		System.out.println();
	}
	
}





public class MyListTest {

	public static void main(String[] args) {
		// 创建对象数组
		Object[] d = {10, 11, 12, 13, 14};
		// 创建MyList对象
		MyList m = new MyList(d, 5);
		// 根据下标获取数据
		System.out.println("第一个数据:" + m.get(0));
		System.out.println("第六个数据:" + m.get(5));
		System.out.println("列表的最大长度为" + m.getListLength());
		m.printList();
		// 增加数据
		m.add(15);
		System.out.println("第六个数据:" + m.get(5));
		System.out.println("列表的最大长度为" + m.getListLength());
		m.printList();
		// 删除数据:通过下标
		m.remove(1);
		m.printList();
		// 删除数据:通过数据
		m.remove(13);
		m.printList();
	}

}




猜拳

```java
package com;

import java.util.Scanner;

public class Mora {
    private int n;  //局数
    private int userIntegral;   //用户积分
    private int aiIntegral;   //机器人积分

    public int getN() {
        return n;
    }

    public void setN(int n) {
        this.n = n;
    }

    public int getUserIntegral() {
        return userIntegral;
    }

    public int getAiIntegral() {
        return aiIntegral;
    }

    public Mora(int n) {
        this.n = n;
        userIntegral = 0;
        aiIntegral = 0;
    }

    public Mora() {
        n = 11;
        userIntegral = 0;
        aiIntegral = 0;
    }

    public void startGame(){
        System.out.println("猜拳游戏开始,总共"+n+"局");
        int num = 1;//当前局数
        Scanner input = new Scanner(System.in);
        while(num <= n){
            System.out.println("---------第"+num+"局----------");
            System.out.print("用户输入数字(1.剪刀 2.石头 3.布)");
            int userMora = input.nextInt();//用户猜拳
            if(userMora >3  || userMora < 1){
                System.out.println("输入错误请重新输入");
                continue;
            }
            System.out.print("用户输入:");
            switch (userMora){
                case 1:
                    System.out.println("剪刀");
                    break;
                case 2:
                    System.out.println("石头");
                    break;
                case 3:
                    System.out.println("布");
                    break;
            }
            int aiMora = (int)(Math.random()*3+1);//机器人猜拳
            System.out.print("机器人输入:");
            switch (aiMora){
                case 1:
                    System.out.println("剪刀");
                    break;
                case 2:
                    System.out.println("石头");
                    break;
                case 3:
                    System.out.println("布");
                    break;
            }

            if(userMora == aiMora){
                System.out.print("平局\t");
                num++;
            }else if((userMora == 1 && aiMora ==3)||(userMora == 2 && aiMora ==1)||(userMora == 3 && aiMora ==2)){

                num++;
                userIntegral++;
                System.out.print("用户得分\t");
            }else {
                num++;
                aiIntegral++;
                System.out.print("机器人得分\t");
            }
            System.out.println("当前比分(用户:机器人):"+userIntegral+":"+aiIntegral);

        }
        if(userIntegral > aiIntegral){
            System.out.println("用户获胜");
        }else  if(userIntegral < aiIntegral){
            System.out.println("机器人获胜");
        }else
            System.out.println("双方打平");

    }
}

package com;

public class MoraTest {
    public static void main(String[] args) {
        Mora mora = new Mora(5);
        mora.startGame();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值