Eclipse插件 二叉树排序 numpy json string oracle bluetooth x86 react视频教程 oracle一键卸载工具 java数据分析 mysql更新多个字段 移动端上传图片插件 hash怎么下载 oracle时间格式化 dwf文件怎么转成dwg 车载u盘 mysql插入 搭建java开发环境 java函数 java获取数据类型 linux用户管理 Ext2Fsd js删除节点 c语言表白代码 vbs表白代码 millenium 键盘指法练习软件 微信砍价活动怎么做 gg修改器下载 phpword bz2解压 rpm卸载命令 facetime要钱吗 ajaxpro Mapper dnf胜利的证明有什么用 夜之魇掉落 女圣骑 dbgview
当前位置: 首页 > 学习教程  > 编程语言

Java之三大特征

2021/1/13 20:39:15 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

三大特征 一、面向对象语言 面向对象的语言一般应该具备封装、继承、多态三大特征。 任何具备有这三大特征的语言都可以认为是面向对象的语言。 二、封装 封装可以是对属性的封装(包括赋值和取值),也可以是对方法的封装。 封装是指隐藏内部的…

三大特征

一、面向对象语言

面向对象的语言一般应该具备封装、继承、多态三大特征。

任何具备有这三大特征的语言都可以认为是面向对象的语言。

二、封装

封装可以是对属性的封装(包括赋值和取值),也可以是对方法的封装。

封装是指隐藏内部的实现细节,公开一些使用的方式。

有两个访问修饰符需要关注:

public 表示公开,在任何地方都可以访问

private 表示私有,只有在本类中可以访问

2.1 属性的封装
  1. 将属性设置为私有(private)
  2. 提供两个公有的(public)方法来访问属性(setter、getter)。
  3. 在对应的访问方法中设置相应的访问条件
public class Student {
	private String name;
	private int age; // 不能被外部直接访问
	String sex;
	
	// 赋值方法
	// 规则set加上属性的名称(驼峰式命名)
	// setter
	public void setAge(int age) {
		if(age > 0 && age <= 160) {//年龄需要判断一下,要符合现实情况
			this.age = age;
		}else {
			this.age = 18;
		}
	}
	
	// getter
	// 取值的方法
	// 规则是get加上属性的名称
	public int getAge() {
		return this.age;
	}
	
	public String getName() {
		if(this.name == null) {
			return "";
		}
		return this.name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
}
2.2 方法的封装

就是指需要对外公开的方法使用public来进行公开,不需要对外公开的方法使用private进行私有化,以达到外部调用者只需要关注常用的方法,而不必关心细节。

/*
	 * 考试
	 */
public void exam() {
    this.openPaper();
    this.answer();
    this.colorPaper();
    this.submit();
}

private void openPaper() {
    System.out.println("打开试卷");
    System.out.println("检查试卷");
    System.out.println("填写信息");
}

private void answer() {
    System.out.println("答题");
}

/*
	 * 涂答题卡
	 */
private void colorPaper() {
    System.out.println("涂答题卡");
}

private void submit() {
    System.out.println("提交试卷");
}

外部只需要考试方法即可,不需要关注其他的考试过程的细节方法。

三、继承

3.1 继承的概念和父类的抽取

在生活中,继承一般指遗产,金钱等方面的继承关系,例如,遗产继承、子承父业等。

在程序中,继承是指,子类会保留父类的所有的特征和行为。

在程序设计时,需要考虑父类的抽取。

  1. 所有的子类共同的属性和行为抽取。
  2. 父类的名称需要考虑最直接的父类(依据项目业务)。
3.2 继承代码实现

注意:在Java中,类只能够单继承(只能直接继承一个类),但是可以多级继承,例如:A继承B,B继承C,就相当于A既继承了B又继承C。

一旦继承了某一个类,理论来说就继承该类的所有属性和方法。

public class Creature {
	public String breed;
	public int age;
	public String sex;
	
	public void breathe() {
		System.out.println("正在呼吸");
	}
}

public class Animal extends Creature{
	public void eat() {
		System.out.println("正在吃");
	}
	
	public void sleep() {
		System.out.println("正在睡");
	}
}


public class Dog extends Animal{
	public String furColor;
	
	public void run() {
		System.out.println("正在跑...");
	}
}

上面的Dog类继承了Animal,Animal又继承了creature。最终Dog类中既包好Animal类中两个方法,又包含creature类中的3个属性一个方法。

3.3 不可继承

构造方法不能继承,因为构造方法名称必须与类名相同,(而继承而来的方法名称不可能又与父类类名相同,又与子类的类名相同。)

private 修饰的属性和方法。由于private修饰的属性和方法,只能本类访问。在子类中无法访问,所以也就意味着没有继承。

如果没有写访问修饰符,默认为default,在不同包里无法访问,我们认为也没有继承。

3.4 访问修饰符

访问修饰符用来修饰属性或者方法。设置该属性或者方法的访问范围。

从小到大排列为:private < 默认的 < protected < public

访问范围:

private : 本类访问

默认的:本类访问、本包访问

protected:本类访问、本包访问、不同包的子类访问

public:随意访问
通过修饰符来修饰,然后判断是否可以访问。

本类本包非本包子类其他
private
default
protected
public
3.5 方法的重写

回顾方法的重载(overload),可以在同一个类,也可以在父子类,方法名称相同,参数列表不同。(返回值类型无参考价值)。

public class Monster {
	// 方法的重载(overload)
	public void hit(String name) {
		System.out.println("怪兽正在打" + name);
	}
	
	public void hit(int i) {
		System.out.println("怪兽正在打" + i);
	}
}

public class GSL extends Monster{
	public void hit(double d) {
		System.out.println("哥斯拉在打" + d);
	}
}

方法的重写(override),需要在父子类或者接口和实现类之间。

方法名称、返回值类型、参数列表、异常声明必须相同,访问修饰符可以不同,在子类中,方法重写的访问修饰符必须与父类相同会更大。

public class Monster {
	protected void hit(String name) {
		System.out.println("怪兽正在使用拳头打" + name);
	}
}

public class GSL extends Monster{
	// 方法的重写(override)
	@Override // 在写代码的时候检查该方法是否是重写的方法
	public void hit(String n) {
		System.out.println("哥斯拉正在使用技能打" + n);
	}
}

@Override用来检查当前方法是否重写了父类的方法,避免程序员出现拼写错误。

方法的重写,一般是父类的方法作用达不到子类的要求,在子类重写(覆盖)父类的方法。

3.6 super关键字

super表示调用父类的方法或属性。

this表示调用当前类的方法或属性。

例如:如果在子类中重写了父类的方法,但是又需要调用父类中的该方法,可以使用super。

public class A {
	// 很多属性
	public void update() {
		System.out.println("修改了50个属性");
	}
}
public class B extends A{
	// 添加了一个属性
	@Override
	public void update() {
		super.update(); // 调用父类的方法
		System.out.println("修改了一个属性");
	}
}

如果子类中定义了一个属性名称跟父类属性的名称一致,会覆盖掉父类的属性,此时,如果在子类的方法中,需要调用父类的属性,可以使用super关键字。

public class A {
	public int index = 5;
	
	// 很多属性
	public void update() {
		System.out.println("修改了50个属性");
	}
}
public class B extends A{
	public int index = 10;
	// 添加了一个属性
	@Override
	public void update() {
		super.update(); // 调用父类的方法
		System.out.println("修改了一个属性");
		System.out.println(super.index); // 调用父类的属性
		System.out.println(index);
	}
}

继承时对象的创建过程:

在创建子类对象时,会先创建父类的对象,调用父类的构造方法,再调用子类的构造方法。

3.7 没有默认的无参构造方法时super关键字用法

当一个类继承另一个类时,创建该类的对象,需要先创建父类的对象,并调用其父类的构造方法。默认情况下会调用父类的无参构造方法。

当父类没有提供无参构造时(提供了有参的构造),无法去默认调用父类的无参构造,所以此时需要在子类的构造方法中显示(手动)的调用父类提供的构造方法。必须要保证在创建子类对象时,能够先创建父类的对象。

public class A {
	public int a = 5;
	
	public A(int a) {
		this.a = a;
	}
}
public class B extends A{
	public int b = 10;
	
	public B() {
		super(5); // 显示调用父类的构造方法
		System.out.println("B被创建");
	}
}

this和super的区别

this和super都可以调用属性方法和构造方法。

this表示调用当前类的对象的属性、方法和构造。

super表示调用父类的属性、方法和构造。

总结继承过程中需要注意的内容:

  1. 有一些情况下,部分内容不可被继承。(父类的私有属性或方法)
  2. 在父类和子类中,属性名称相同会覆盖,方法相同也会覆盖,需要使用super来调用被覆盖的属性和方法。
  3. 在继承过程中,默认的无参构造会自动调用父类的无参构造,如果父类没有提供无参构造,则必须在子类的构造方法中显示调用父类的无参构造,保证在创建子类对象时,可以先创建父类对象。

四、多态

多态在生活中是指同一个事物在不同的角度有不同的叫法,比如一个人在老师的眼里是学生,在家长的眼里是孩子。

在程序中,多态是指,同一个对象可以使用不同的父类来引用。例如,可以使用动物类来引用一只狗的对象。也可以使用狗类变量来引用该对象。

注意:在程序中,只有父类的引用可以直接引用子类的对象(此时不能访问子类特有的属性或方法)。而不能直接使用子类的引用来引用父类的对象(会报错,需要强制转换)。

public class Animal {
	private String breed; // 品种
	private int age;
	private String sex;
	
	public void eat() {
		System.out.println("动物在吃");
	}
    // 省略getter和setter
}
public class Dog extends Animal{
	private String furColor;
	
	public void playBall() {
		System.out.println("狗在接球");
	}
}
public static void main(String[] args) {
    Dog dog = new Dog();
    dog.eat();
    dog.playBall();

    Animal a = new Dog(); // 使用父类的变量来引用子类的对象
    a.eat();

    // Dog d = new Animal(); // 此处报错,需要强制转换
}

在程序中,可以定义方法,参数为父类的引用,在实际调用方法时,传入子类的对象,当方法中使用父类的引用去调用方法时,会自动调用子类中重写后的方法,称为多态的应用。

public class Animal {
	public void eat() {
		System.out.println("动物在吃");
	}
}
public class Cat extends Animal{
	@Override
	public void eat() {
		System.out.println("猫在吃。。。");
	}
}
public class Dog extends Animal{
	@Override
	public void eat() {
		System.out.println("狗在吃骨头");
	}
}
public class Master {
	public void feed(Animal animal) { // 方法中定义的父类的引用
		animal.eat();
	}
}
public static void main(String[] args) {
    Master m = new Master();
    Dog d = new Dog();
    m.feed(d); // 传参的时候传递的子类的对象,最终会调用子类中重写后的方法

    Cat c = new Cat();
    m.feed(c);
}

应用场景:

  1. 作为参数(上面的示例)
  2. 作为返回值(下面的示例)
public Animal getAnimal() {
    return new Dog();
}
4.2 转型

向上转型(装箱),此过程是默认完成的。例如:Animal a = new Dog();

此方式会隐藏子类特有的属性和方法。

向下转型(拆箱),此过程需要手动编码实现,有风险,应该使用instanceof关键字判断类型是否一致。

public void feed(Animal animal) {
    animal.eat();
    if(animal instanceof Dog) { // 判断是否Dog类型的对象
        Dog d = (Dog)animal; // 向下转型(有风险)
        d.playBall();
    }else if(animal instanceof Cat) {
        Cat c = (Cat)animal;
        c.giao();
    }else if(animal instanceof Fish) {
        Fish f = (Fish)animal;
        f.swim();
    }
}

本文链接: http://www.dtmao.cc/news_show_600390.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?