【Java】---三大特性

java之三大特性

封装、继承、多态



一、三大特性有哪些?

java的三大特性,包括:封装、继承、多态。


二、封装

2.1 概念

尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限。

2.2 为什么学封装?

当我们在调用对象的属性时,往往通过对象名.属性名这种形式来获取数据或修改数据。以下面的user类的数据调用来说明:

class User{
	String name;//姓名
	double money;//余额
	int age;//年龄
	public void show(){//打印信息
		System.out.printf("姓名:%s\n余额:%f\n年龄:%d",this.name,this.money,this.age);
	}
}
public class Test{
	public static void main(String[] args){
		User user = new User();//创建对象
		//为属性赋值
		user.name = "张三";
		user.money = 100;
		user.age = 16;
		user.show();
	}
}

输出结果:

姓名:张三
余额:100.000000
年龄:16

这很正常,对吧?
但是在生活中,属性的赋值不是在代码中写,而是通过输入来控制,即:

Scanner input = new Scanner(System.in);
System.out.println("请输入姓名:");
user.name = input.next();
System.out.println("请输入余额:");
user.money = input.nextDouble();
System.out.println("请输入年龄:");
user.age = input.nextInt();
user.show();//打印输入的信息

以上这种提示+输入的流程才是程序设计中的常态
身为程序设计者的我们,自然希望属性是正确的,但:

请输入姓名:
awwrg
请输入余额:
-123523
请输入年龄
-999

输出结果:

姓名:awwrg
余额:-123523
年龄:-999

上面的数据,很明显,是不符合现实情况的
客观上:

  1. 就目前的技术而言,并没有办法对属性的赋值加以控制
  2. 毫无意义的数据存入我们的程序中,对于数据库来说就是垃圾

主观上:

  1. 我们不能赌数据输入者的智商和道德
  2. 我们希望程序能按照我们想要的效果运行

所以我们需要对属性加以限制,需要对属性进行封装(private):

private int age;

private是一个访问修饰符,它可以让类中被其修饰的数据无法直接获取和修改。
那我们怎么去调用属性呢?
private虽然禁止了类外调用属性,但在类中是不加限制的
所以我们可以编写专门的方法去获取和设置数据:
public 数据类型 get():专门用于获取类中被封装的数据。

public int getAge(){//被获取的数据开头大写
	return this.age;//返回需要获取的数据
}

public void\boolean set(数据类型 形参):专门用于设置类中被封装的数据

public boolean setAge(int age){//对
	if(age <= 0 || age >120)//对数据进行逻辑判断,结合现实情况
		return false;
	this.age = age;//符合要求的数据才会被获取
	return true;
} 

2.3 代码演示

2.3.1 类中设置

class User{
	//封装的属性只能在类中使用
	private String name = "张三";//封装姓名,设置默认值
	private double money;//封装余额
	private int age = 18;//封装年龄,设置默认值
	
	public String getName(){//专门用于获取姓名的方法
		return this.name;//直接返回
	}
	public boolean setName(String name){//专门用于设置姓名的方法
	//本人太菜,暂时还不会如何判断姓名是否正确···
	//经过一系列逻辑判断后···
		this.name = name;//确实是姓名,获取
		return true;
	}
	public double getMoney(){//专门用于获取余额的方法
		return this.money;
	}
	public boolean setMoney(double money){//专门用于设置余额的方法
		if(money < 0)//钱不可能是负数
			return false;
		this.money = money;
		return true;
	}
	public int getAge(){//专门用于获取年龄的方法
		return this.age;
	}
	public boolean setAge(int age){//专门用于设置年龄的方法
		if(age <= 0 || age > 120)//年龄不可能是负数,世界上最长寿的人也就120吧。。
			return false;
		this.age = age;
		return true;
	}
}

原则上来讲,类中的任何属性都需要封装

2.3.2 主类调用

import java.util.Scanner;
public class Test{
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		User user = new User();//创建对象
		System.out.println("请输入姓名:");
		String name = input.next();
		if(!user.setName(name))//判断数据是否正确
			System.out.println("姓名错误!");
		System.out.println("请输入年龄:");
		int age = input.nextInt();
		if(!user.setAge(age))
			System.out.println("年龄错误!");
		System.out.println("请输入余额:");
		double money = input.nextDouble();
		if(!user.setMoney(money))
			System.out.println("余额错误!");
		System.out.println("姓名:" + user.getName());//通过get方法获取数据
		System.out.println("年龄:" + user.getAge());
		System.out.println("余额:" + user.getMoney());
	}
}

输出结果:

请输入姓名:
张三
请输入年龄:
-9
年龄错误!
请输入余额:
1515
姓名:张三
年龄:18
余额:1515.000000

2.4 注意事项

  1. private不能作为类的访问修饰符
  2. private修饰的属性或方法,只能在类中直接调用
  3. 添加privave时,一定要添加get()set()方法,不然没有任何意义

三、继承

3.1 概念

继承:一个类继承另一个类可以被继承的成员。关键字为extends

3.2 方法重写

子类将从父类继承而来的方法进行改变。

规则:

  1. 子类重写父类方法时,须与父类方法的方法名一致、返回值类型一致、参数列表一致(参数类型参数数量参数顺序
  2. 子类重写父类的方法,在子类中被优先调用,可使用super.方法名调用父类方法。
class Animal{
	public void show(){//父类的方法
		System.out.println("动物正在吃东西···");
	}
}
class Cat{
	public void show(){//子类重写父类的方法
		System.out.println("猫正在吃东西···");
	}
}

3.3 代码演示

父类–Animal:

class Animal{//动物类
	private String nickname;
	private int age;
	private String furcolor;

	public void eat(){
		System.out.println("动物在吃东西···");
	}
	public void sleep(){
		System.out.println("动物在睡觉···");
	}
	public String getNickname(){
		return this.nickname;
	}
	public void setNickname(String name){
		this.nickname = nickname;
	}
	public int getAge(){
		return this.age;
	}
	public void setAge(int age){
		this.age = age;
	}
	public String getFurcolor(){
		return this.furcolor;
	}
	public void setFurcolor(String furcolor){
		this.furcolor = furcolor;
	}
	
}

子类–Cat:

class Cat extends Animal{//猫类,继承了动物类

	public void eat(){//重写父类的eat方法
		System.out.println(getNickname() + "猫在吃东西···");//调用父类方法
	}
	public void sleep(){//重写父类的sleep方法
		System.out.println(getNickname() + "猫在睡觉···");//调用父类方法
	}
	public void show(){//显示动物信息
		System.out.println("昵称:" + getNickname());
		System.out.println("年龄:" + getAge());
		System.out.println("毛色:" + getFurcolor());
	}
}

主类:

import java.util.Scanner;
public class Test{
	public static void main(String[] args){
		Scanner input = new Scanner(System.in);
		Cat cat = new Cat();//创建子类对象
		System.out.println("请输入昵称:");
		cat.setNickname(input.next());//调用父类方法
		System.out.println("请输入年龄:");
		cat.setAge(input.nextInt());//调用父类方法
		System.out.println("请输入毛色:");
		cat.setFurcolor(input.next());//调用父类方法
		cat.show();
		cat.eat();
		cat.sleep();
	}
}

输出结果:

请输入昵称:
小黑
请输入年龄:
3
请输入毛色:
黑色
昵称:小黑
年龄:3
毛色:黑色
小黑猫在吃东西···
小黑猫在睡觉···

3.4 特点

  1. 子类可直接调用父类的非private属性和方法。
  2. 重写父类方法时,修饰符可以与父类方法相同,或更宽广,不能更窄!!

四、多态

4.1 概念

多态有两种表现形式:向上转型向下转型

4.1.1 向上转型

使用父类引用,获取子类的对象:
父类类名 对象名 = new 子类类名();

Animal cat1 = new Cat();

4.1.2 向下转型

仅限向上转型后:
使用子类引用,将经过向上转型的对象强转为子类类型
子类类名 对象名 = (子类类型) 向上转型过的对象;

Cat cat2  = (Cat)cat1;

例:
父类–Animal:

public class Animal{

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

子类–Cat:

public class Cat extends Animal{//继承了Animal类
	public void eat(){//子类重写父类的方法
		System.out.println("猫咋吃东西");
	}
	public void play(){//子类独有的方法
		System.out.println("猫在玩毛线");
	}
}

主类创建对象:

public clas Test{
	public static void main(String[] args){
		Animal cat = new Cat();//向上转型
		cat.eat();//此时cat只能调用父类的成员及子类重写父类的方法
		Cat cat2 = (Cat)cat;//向下转型
		cat2.play();//cat2是纯正的Cat类型,可以调用其独有的方法
	}
}

输出结果:

猫在吃东西
猫在玩毛线

4.2向上转型的应用

4.2.1 作为方法参数

向上转型可应用在方法中,作为方法的参数
父类中:

public class Animal{
	String nickname;
	int age;
	String furcolor;
	
	public void show(Animal an){//通过向上转型的方式,获取子类对象,不必单独指定子类类型
		System.out.println("姓名:" + an.nickname);
		System.out.println("年龄:" + an.age);
		System.out.println("毛色:" + an.furcolor);
	}
}

子类Cat和Dog:

class Cat extends Animal{
	Cat(){//无参构造方法
	}
	Cat(String nickname,int age,String furcolor){
		super.nickname = nickname;
		super.age = age;
		super.furcolor = furcolor;
	}
}
class Dog extends Animal{
	Dog(){//无参构造方法
	}
	Dog(String nickname,int age,String furcolor){
		super.nickname = nickname;
		super.age = age;
		super.furcolor = furcolor;
	}
}

主类中

public class Test{
	public static void main(String[] args){
		Animal an = new Animal[3];
		Cat cat = new Cat("小黑",3,"黑色");
		Dog dog = new Dog("旺财",2,"棕色");
		an.show(cat);//子类对象通过向上转型的方式接收
		an.show(dog);
	}
}

输出结果:

姓名:小黑
年龄:3
毛色:黑色
姓名:旺财
年龄:2
毛色:棕色

4.2.2 作为数组元素

子类对象可作为父类对象数组中的元素

public class Test{
	public static void main(String[] args){
		Animal[] an = new Animal[2];//父类对象数组
		Cat cat = new Cat("小黑",3,"黑色");
		Dog dog = new Dog("旺财",2,"棕色");
		an[0] = cat;//子类对象可通过向上转型的方式作为父类对象数组中的元素
		an[1] = dog;
	}
}

4.3 特点

  1. 向上转型的对象,可以调用父类的属性和方法,以及子类重写的方法
  2. 向上转型的对象,不能调用子类独有的属性和方法!!
  3. 向下转型的对象,只是子类的对象,可以调用子类独有的属性及方法。

总结

这是我写的第二篇博客,新人一个,如有错误或建议请多在评论区批评指正,谢谢!

  • 31
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值