第三周复习

本周我们接触了三大特性

何为三大特性

  1. 封装
  2. 继承
  3. 多态
  • 封装是将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问,保护数据的安全。
  • 继承是子类拥有父类的所有属性和方法(除了private修饰的属性不能拥有),从而实现了实现代码的复用;
  • 多态是使用父类引用接受,不同的子类的对象实例,父类引用调用相同的方法,根据子类不同的实例,产生不同的结果

封装

尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限。
使用访问修饰符将属性私有,仅本类可见。

  • 使用

在公共的访问方法内部,添加逻辑判断,进而过滤掉非法数据,以保证数据安全。

public class Student {
	//私有属性,本类可见,其他位置不可见
	private int age;
	private String sex;
	private String name;
	public int getAge() {
		return age;
	}
	
	//getxx(),setxx()方法封装
	//过滤掉非法数据
	public void setAge(int age) {
		if (age>0&&age<150) {
			this.age = age;//对非法数据进行判断何过滤
		}else {
			this.age=18;
		}
		
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
  • 注意
    对于私有属性的访问,可通过get/set方法对其访问

继承

  • 何为继承
程序中的继承,是类与类之间特征和行为的一种赠与或获得。
两个类之间的继承关系,必须满足“is a”的关系

从我们们生活中的例子延伸:有很多继承的例子

  • 父子之间的继承
  • 狗是一种动物、狗是一种生物、狗是一种物质。
  • 但在Java中,子类继承只能单继承但可以多级继承,例如:狗继承动物,动物继承生物,生物继承物质

继承关键字:extends

继承实例:

  • 先写一个Animal父类
public class Animal {
	//父类私有属性
	private String name,type,sex,color;
	private int age;
	//动物类叫的方法
	public void yell(){
		System.out.println("--");
	}
	//动物父类睡觉的方法
	public void sleep() {
		System.out.println("趴着睡");
	}
	public void eat() {
		System.out.println("+++++");
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
  • 狗继承父类
public class Dog extends Animal{
	public void yell(){
		System.out.println("汪汪叫");
	}
	//狗子类重写父类的吃
	@Override
	public void eat() {
		System.out.println("啃骨头");
	}
	
}

这个例子用到了方法的重写,那么我们来复习重写

  • 为什么要重写
    因为虽然子类可以继承父类的方法,但父类提供的方法无法满足子类需求时,可在子类中定义和父类相同的方法进行重写
  • 重写规则
  方法名和参数列表和父类相同
  返回值类型和父类相同
  访问修饰符可和父类相同或者更加宽泛,
  例如父类为protected保护类,而子类可使用protected或public
  
  • 重写和重载的区别
    二者仅仅一字之差,但却区别很大
重载、重写都有一个相同点:方法名相同
区别:重载方法的参数个数类型顺序的不同都可以构成重载,和访问修饰符、返回值无关

在这里插入图片描述

重写方法

public class Test {
	public static void main(String[] args) {
		A a=new A();
		/*
		 * 构造函数是创建对象时用来给变量赋值的
		 * 例如:public A(int age)
		 * A a=new A(22)
		 * 而a.A();是错的
		 * */
		a.Test1();
		a.sleep();
		A a2=new A(20);
		
	}
}

class A extends SuperTest{
	int age=22;
	public void Test1() {
	System.out.println(this.age);
	//调用父类的属性
	System.out.println(super.age);

	}


	public void sleep() {
		super.sleep();
		
	}
	//在子类里面调用父类的有参构造函数
	public A(int age) {
		super("子类");
	}
	/*super()表示调用父类中的构造方法

	1、子类继承父类,子类的构造方法的第一行,系统会默认编写super(),在调用子类的构造方法时,先调用父类的无参数构造方法

	2、如果父类中只有有参数构造方法,那么子类继承父类时会报错,因为子类的构造方法在默认调用父类无参数构造方法super()不存在。

	3.如果子类的第一行编写了this()、this(实参),因为this()也会占用第一行,所以此时就会将super()挤掉,就不会调用父类构造方法。
	*/
	//在子类里面调用父类的无参构造函数
	public A() {
		super();
	}
	
}

多态

  • 多态性的理解

可以理解为一个十五的多种形态,就比如一个人在不同人角度看是具有不同的形态,在老师眼中是个学生,在父母眼中是个孩子…但他终究是属于一个个体是一个人。

  • 何为多态性:
    在Java中是指:父类的引用指向子类的对象,或者说子类的对象赋给父类使用
  • 多态性的举例

1.先定义一个父类

public class Animal {
	String name,type,sex,color;
	public void yell() {
		System.out.println("叫");
	}
	public void sleep(){
		System.out.println("睡睡睡");
	}
	public void eat(){
		
	}
	
}

2.构建子类

public class Cat extends Animal  {
	public void yell() {
		System.out.println("喵喵喵");
		//super.yell();
	}	
	public void sleep() {
		System.out.println("趴着睡");
	}
	@Override
	public void eat() {
		System.out.println("吃猫粮中......");
	}
}
public class Dog extends Animal{
	
	@Override
	public void yell() {
		System.out.println("汪汪汪");
		//super.yell();
	}	
	public void sleep() {
		System.out.println("趴着睡");
	}
	@Override
	//方法重写
	public void eat() {
		System.out.println("吃狗粮中.....");
	}
	
}

3.父类作为形参传入

public class Master {
	//父类作为形参
	public  void feed(Animal animal) {
		System.out.println("第一次喂食");
		animal.eat();
	}
}
Master m=new Master();
Dog dog=new Dog();
m.feed(dog);//子类对象作为实参传值,实际上就是Animal animal=new Dog()
/*
	也可以是Animal animal=new Dog();m.feed(animal),也可以达到同样的效果
*/

  • 向上转,向下转

1.向上转型:为多态,即父类的引用指向子类的对象;
例如Animal animal=new Dog();这就是向上转,子类转向父类;

2.向下转型:将父类引用中的真实子类对象,强转回子类本身类型,称为向下转型,类似于变量的强制转型。

在这里插入图片描述

注意:Animal animal=new Dog();Dog dog1=(Dog) animal;这就相当于向下转从父类转回子类,这样可以调用子类的方法。

Dog dog=new Dog()直接new对象,二者区别,直接调用不需要继承父类,既然这样为什么不直接new对象就好。原因就出在于继承,我继承父类的东西,而且使用多态向上转了,但这时我又想使用子类的东西,这样向下转型就要使用了。直接实例化对象是不需要继承父类的,也可以使用对象的属性和方法。

  • instanceof 关键字

向下转型前,应判断引用中的对象真实类型,保证类型转换的正确性。
语法:父类引用 instance of 类型 //返回boolean类型结果

注意
a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
如果 a instanceof A返回true,则 a instanceof B也返回true.其中,类B是类A的父类。

实例

//因为不清楚顾客会挑选那一只动物,所以用instanceof判断
if (animal instanceof Dog) {
			Dog dog=(Dog) animal;
			dog.yell();//如果dog是Dog类的实例则调用yell方法

多态的两种使用场景

1.多态作为返回值类型:

public Animal Sell(int num) {
		Animal animal=null;
		if (num==1) {
			animal=new Cat();
		}else if (num==2) {
			animal=new Dog();
			
		}else if (num==3) {
			animal=new Snake();
		}else if(num==4){
			animal=new Fish();
		}else {
			System.out.println("输入错误!");
		}
		return animal;
	}

2.多态作为形参:

public void func(Animal animal){//Animal animal = new Dog();
		animal.eat();
		animal.shout();
	}

三个关键字

  • abstract
  • static
  • final

abstract抽象

  • 何为抽象:

似是而非的,像却又不是;具备某种对象的特征,但不完整

  • 抽象类、抽象方法:

1.抽象类
被abstract修饰类,无法独立存在,此类不能new对象,即不可实例化。
被abstract修饰的类,称为抽象类。
抽象类意为不够完整的类、不够具体的类。抽象类中一定有构造器,便于子类实例化时调用。抽象类,一般都用于继承。

2.abstract修饰方法:抽象方法

抽象方法只方法的声明,没方法体;void get();直接加分号结束,不需要大括号的方法体;
包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的,抽象类不一定有抽象方法
若子类重写了父类中的所的抽象方法后,此子类方可实例化
若子类没重写父类中的所的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰

注意
1.abstract不能用来修饰:属性、构造器等结构
2.abstract不能用来修饰私方法、静态方法、final的方法、final的类

static静态

何为静态:

  • 静态(static)可以修饰属性和方法。
  • 称为静态属性(类属性)、静态方法(类方法)。
  • 静态成员是全类所有对象共享的成员。
  • 在全类中只有一份,不因创建多个对象而产生多份。
  • 不必创建对象,可直接通过类名访问。

静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。
说明:
① 静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
② 静态变量的加载要早于对象的创建。
③ 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。

final 最终的

1.可以用来修饰:类、方法、变量

2.1 final 用来修饰一个类:此类不能被其他类所继承。

  •      比如:String类、System类、StringBuffer类
    

2.2 final 用来修饰方法:表明此方法不可以被重写

  •  	比如:Object类中getClass();
    

2.3 final 用来修饰变量:此时的"变量"就称为是一个常量

  1. final修饰属性:可以考虑赋值的位置:显式初始化、代码块中初始化、构造器中初始化
  2. final修饰局部变量:
  • 尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。
    

接口(重点)

  • 概念:

接口相当于特殊的抽象类,定义方式、组成部分与抽象类类似。使用interface关键字定义接口。

  • 特点:

没有构造函数,不能创建对象。
只能定义:公开静态常量、公开抽象方法。
实例:

public interface MyInterface {
	//公开的静态常量
	//public static final String NAME="接口1";
	String NAME="接口1";
	//公开的抽象方法
	//public abstract void method1();
	void method();	
}

实现类:

public class Impl implements MyInterface1{

	@Override
	public void method() {
		System.out.println("method");
	}

}

注意

1.接口使用上也满足多态性
2.接口,实际上就是定义了一种规范
3.开发中,体会面向接口编程!
4.接口中不能定义构造器的!意味着接口不可以实例化
Java开发中,接口通过让类去实现(implements)的方式来使用.
如果实现类覆盖了接口中的所抽象方法,则此实现类就可以实例化
如果实现类没覆盖接口中所的抽象方法,则此实现类仍为一个抽象类
Java类可以实现多个接口 —>弥补了Java单继承性的局限性
接口与接口之间可以继承,而且可以多继承

  • 接口规范

任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
实现接口中的抽象方法时,访问修饰符必须是public。
同父类一样,接口也可声明为引用,并指向实现类对象。

public class TestPerson2 {
	public static void main(String[] args) {
		
		Flyable flyable=new Person("小张",22);
		flyable.fly();


		Fireable fireable=new Person("小李", 15);
		fireable.fire();
	}
}
  • 接口实现多态

接口实现多态:使用接口作为方法的参数和返回值,实际赋值实现类对象实现多态。

定义接口

public interface Runnable{
	//跑
    void run();
}

父类

public abstract class Animal {
	public void eat() {
		System.out.println("吃");
	}
	public void sleep() {
		System.out.println("睡");
	}
}

实现类

public class Dog extends Animal implements Runnable,Swimable{
	
	public void shout() {
		System.out.println("狗狗开始叫...");
	}

	@Override
	public void swim() {
		System.out.println("狗狗游泳...");
	}

	@Override
	public void run() {
		System.out.println("狗狗跑步...");
	}
}

  • 宏观接口,接口回调

宏观概念:接口是一种标准、规范。

接口回调:先有接口的使用者,后有接口的实现者。

  • 接口的好处:

程序的耦合度降低。
更自然的使用多态。
设计与实现完全分离。
更容易搭建程序框架
更容易更换具体实现。

课堂问题

  • java有多少种方法获取一个对象的实例

new对象
反射机制
调用对象的clone()方法
反序列化

  • 访问修饰符,除了属性,还能用在什么地方

可以修饰方法和类

  • 为什么不能直接输出super

从规范上来说,super永远不可能作为单独的表达式,后面必须加上后缀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值