带妹学Java第五天(至抽象类)

知识点

1.继承

2.supper

3.this

4.继承中构造方法

5.方法重写

6.final关键字

7.多态

8.抽象类

重点

1.继承

  • 继承的特点

Java只支持单继承,不能支持多继承,但支持多层继承

  • 继承的注意事项
    子类只能访问父类非私有的成员变量和方法

2.supper关键字

  • 当子类要访问属性和方法的时候的特点
    如果子类自己有这个属性和方法,就访问自己的
    如果子类没有这个属性和方法,就找父类
    如果子类和父类都有这个属性和方法,一定想访问父类的,那么在调用属性和方法的时候,前面加个super.关键字
supper调用父类的构造方法

class Animal{
	String name;
	int legs;
	public Animal(){}
	public Animal(String name,int legs){
		this.name = name;
		this.legs = legs;
	}
	public void say(){
		System.out.println("我是" + name + " 我有" + legs + "条腿");
	}
}

class Cat extends Animal{
	public Cat(){}
	public Cat(String name,int legs){
	/*	this.name = name;
		this.legs = legs;*/
		super(name, legs);//调用有参构造方法
		
	}
}

3.this关键字的深入讲解

  • this的作用
    this指的是当前类的对象引用
  • this可以调用本类的成员属性 this.成员属性
  • this可以调用本类的成员方法 this.成员方法
  • this也可以调用父类的成员方法(在本类没有的情况下)this.父类方法、this.父类属性
  • this可以调用本类的构造方法 this(…)

4.继承中构造方法的关系【掌握】

  • 子类中所有的构造方法默认都会访问父类中“空参数的构造方法”
    为什么:
    因为子类会继承父类中的数据,可能还会使用父类的数据。
    所以,子类初始化之前,一定要先完成父类数据的初始化。

  • 每一个构造方法的第一条语句默认都是:super()
    Constructor call must be the first statement in a constructor

  • Object类是最顶层的父类。
    如果一个类不继承任何一个类,他的父类就是Object
    class Person extends Object
    class Person
    上面两行代码效果是一样

5.继承中构造方法的注意事项

  • 父类没有无参构造方法,子类怎么办?

    子类必须创建无参构造方法,内还要调用父类构造方法
    子类实现有参的构造方法
    父类自己实现无参构造方法

  • 注意事项
    super(…)或者this(….)必须出现在构造方法的第一条语句上

6.方法重写

  • 什么是方法重写
    方法重写是指子父类出现了一模一样的方法 重写这个概念只是存在子类和父类中默认情况下,子类的重写的方法会有一个标识@Override
  • 方法重写的应用
    当子类需要父类的功能,而子类有自己特有内容时, 可以重写父类中的方法。这样,即沿袭了父类的功能,又定义了子类特有的内容。
  • 方法重写的注意事项
  1. 父类中私有方法不能被重写,因为父类私有方法子类根本就无法继承
  2. 子类重写父类方法时,访问权限最好就一致

7.final

  • final修饰特点

修饰类,类不能被继承,相当于做了丁克
修饰变量,变量就变成了常量,只能被赋值一次
修饰方法,方法不能被重写

  • 修饰变量

final修饰变量叫做常量,一般会与public static共用
常量命名规范,如果是一个单词,所有字母大写,如果是多个单词,每个单词都大写,中间用下划线隔开,如 public static final MAX_AGE = 125;

  • final修饰局部变量特性

1.修饰基本类型,是值不能被改变
2.修饰引用类型,是地址值不能被改变,对象中的属性可以改变
3.修饰引用类型不可以再New

8.多态

8.1 什么是多态(polymorphic)
多态就是事物存在的多种形态
8.2 Java中存在多态的前提条件

要有继承关系
要有方法重写
要有父类引用指向子类对象

8.3 多态的访问、编译、运行规律

  • 多态访问成员变量-编译看左边(父类),运行看左边(父类)(掌握)
  • 多态访问成员方法-编译看左边(父类) ,运行看右边(子类)(掌握)
  • 多态访问静态方法-编译看左边(父类) ,运行看左边(父类) - 这种写法是不成立(了解)

//永远记住:多态调用方法,执行的效果是看右边
8.4 多态中向上转型和向下转型

  • 向上转型:Person p = new SupperMan();
  • 向下转型:SupperMan sm = (SupperMan)p;
  • 注意:向下转型时,父类的真实对象必须是子类对象,否则会有类型转换异常ClassCastException
    8.5 多态的好处和弊端
  • 好处:方便维护,扩展性好
  • 弊端: 在方法中使用父类当作参数时,方法内部不能使用父类访问子类的属性和方法

9.抽象类

  • 抽象类的概述和特点

1.抽象类:可以理解为看不懂的类
2.抽象类的特点
抽象类和抽象方法必须用abstract关键字修饰
abstract class 类名{}
public abstract void eat();
3.抽象类不能实例化,那么如何进行抽象类实例化?
由具体的子类实例化。其实这也是多态的一种,抽象类多态

4.抽象类不一定有抽象方法,有抽象方法的类一定是个抽象类

5.抽象类的子类
5.1 要么重写抽象类中的所有抽象方法
5.2 要么是抽象类

  • 抽象类成员的特点

1.成员变量:即可以是变量,也可以是常量。
2.abstract不能修饰成员变量(属性),只能修饰类和方法
3.构造方法:抽象类也是有构造方法的,用于子类访问父类数据的初始化
4.成员方法:抽象类的方法可以是抽象的,也可以是非抽象

5.抽象类的成员方法特性:
抽象方法:强制要求子类实现
非抽象方法:子类继承实现自己的业务,提高代码的复用性

练习题

1.学生和老师案例

	分别写个学生和老师类
	相同属性:姓名,年龄
	相同行为:吃饭 
	老师有特有的方法:讲课
	学生有特有的方法:学习

	使用继承将学生和老师代码进行改造
//父类
class Person{
	String name;
	int age;
	public void eat(){
		System.out.println("次饭...");
	}
}

class Student extends Person{
	
	public void study(){
		System.out.println("学习 Java 争取找到一份待遇好的工作。。。");
	}
}

class Teacher extends Person{
	
	
	public void speak(){
		System.out.println("教师讲Java 内容课程....");
	}
	
}

2.超人案例(深入理解多态-隐藏-低调-伪装)

public class Demo01 {

	public static void main(String[] args) {
/*
		超人案例(深入理解多态-隐藏-低调-伪装)

		超人去美国找某某集团的老总谈生意
		超人在别人面前,如果不说自己是超人,在别人面前表现的就是普通人
		老总以为是谈小生意的,但实际是谈大生意
		老总以为他不会飞,实际上他会飞去救人*/
		
		//父类指向子类对象(多态)
		Person p = new SupperMan();
		p.fly();
	}
}

//普通人
class Person{
	public void walk(){
		System.out.println("走....");
	}
	public void fly(){
		System.out.println("我是普通人,不会飞...");
	}
}

//超人
class SupperMan extends Person{
	public void fly(){
		System.out.println("超人飞去救人...");
	}
}

3.多态的编译、运行规律练习题

public class Demo01 {
	public static void main(String[] args) {
		Fu f = new Zi();
		//f.test();//多态访问方法的特点:编译看左边,也就是Fu有没有test方法
		f.show();
	}
}
class Fu{
	public void show() {
		System.out.println("Fu show...");
	}
	
	//public void test(){}
}
class Zi extends Fu{
	public void show() {
		System.out.println("Zi show...");
	}
	public void test() {
		System.out.println("Zi test...");
	}
}

4.抽象类练习

public class Demo02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/*使用抽象类练习老师的案例
		   具体事物:基础班老师,就业班老师
		   共性:姓名,年龄,讲课*/
		
		Teacher teacher1 = new BasicTeacher("gyf",23);
		/*teacher1.name = "gyf";
		teacher1.age = 30;*/
		teacher1.teaching();
		
		System.out.println("================");
		Teacher teacher2 = new JobTeacher();
		teacher2.name = "lp";
		teacher2.age = 18;
		teacher2.teaching();

	}

}

abstract class Teacher{
	String name;
	int age;
	
	public abstract void teaching();

	
	public Teacher() {
		super();//-> public Object(){}
	}


	public Teacher(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	
}

//基础班老师
class BasicTeacher extends Teacher{

	@Override
	public void teaching() {
		System.out.println("我是" + name + " 今年" + age );
		System.out.println("我来教你们Java 基础阶段的内容...");
	}
	
	public BasicTeacher(String name,int age){
		super(name, age);
		/*this.name = name;
		this.age = age;*/
	}
	
}

//就业班老师
class JobTeacher extends Teacher{

	@Override
	public void teaching() {
		// TODO Auto-generated method stub
		System.out.println("我是" + name + " 今年" + age );
		System.out.println("我来教你们Java 就业阶段的内容...");
	}
	
	
	
}

面试题

1.以下代码输出值

class Fu {
	public int num = 10;
	public Fu() {
		System.out.println("fu");
	}
}

class Zi extends Fu {
	public int num = 20;
	public Zi() {
		System.out.println("zi");
	}
	public void show() {
		int num = 30;
		System.out.println(num);
		System.out.println(this.num);
		System.out.println(super.num);
	}
}

public class Test1 {
	public static void main(String[] args) {
		Zi z = new Zi();
		z.show();
	}
}
//结果:30 20 10

2.静态代码块

public class Test {
	public static void main(String[] args) {
		Zi z =new Zi();
	}
}
class Fu {
	static {
		System.out.println("静态代码块Fu");
	}
	{
		System.out.println("构造代码块Fu");
	}
	public Fu() {
		System.out.println("构造方法Fu");
	}
}
class Zi extends Fu {
	static {
		System.out.println("静态代码块Zi");
	}
	{
		System.out.println("构造代码块Zi");
	}
	public Zi() {
		System.out.println("构造方法Zi");
	}
}
/*结果:
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi */

3. 方法重写重载的面试题

  • Overload能改变返回值类型吗?
    overload是指方法重载,重载可以改变返回值类型,方法的重载只看参数列表不同

  • Override重写和Overload重载的区别?
    Override是指方法重写,也就是子类中出现了和父类中方法声明一模一样的方法。
    方法的重写是与返回值类型有关,返回值是一致(或者是子父类)的
    方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值类型无关。

4.abstract相关

4.1 一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义

可以,这么做的目的只有一个,就是不让其它类创建本类对象,交给子类完成

4.2 abstract不能与哪些关键字共存(重点)
abstract和static

  • 1.static修饰的方法是通过类名来调用
  • 2.abstract修饰的方法必须由子类来实现,并由子类对象来调用方法
  • 3.对象方法与类方法是冲突的

abstract和final

  • 1.final修饰的方法是不能被重写的,所以也矛盾

abstract和private

  • 1.private修饰的方法不让子类访问,所以也矛盾
  • */

总结

今天带妹学习了半天,妹子对之前的static、super、this、abstract、final等关键字有些模糊,通过系统的学习,知道了static的特性是类属性,用类名.属性(或者方法)来访问,在静态方法中是没有this关键字的;super在子类中可用来调用父类成员变量和方法,默认子类的构造方法都会由super(),即父类的无参构造方法,这里容易报错,大多是忽略了默认super();this关键字,是调用本类的成员属性、方法、或者构造方法,需要特别注意的是,当本类无属性时,默认会访问父类的相同属性;abstract关键字,主要用在类和方法前,不可修饰属性,类被abstract修饰后,不能实例化(new),修饰的方法的格式是:public abstract void eat();被修饰的方法不能有方法体。final关键字修饰类时,则该类不能被继承;修饰方法时,不能被重写;修饰变量时,不能第2次赋值。代码要天天敲,坚持就是最大的天赋!本套教程,尽量讲的详细,有不当之处,还望指正!适合入门进阶的开发者!配有练习题和面试题!

发布了24 篇原创文章 · 获赞 4 · 访问量 621

猜你喜欢

转载自blog.csdn.net/qq_43488797/article/details/103722033