/*
面向对象(回顾)OOP
O:Oriented
O:Object
P:Programming
类
一类事务的抽象表示(写人的名字,人的年龄)
对象:
是类的实例,生活中真实存在的事物。对象都是通过类产生的。
*/
创建Person类
public class Person {
private String name;
private int age;
//快捷键atl+ins生成get/set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试
public class Test {
public static void main(String[] args) {
//对象的创建和使用
//创建Person类的对象
//数据类型 数据类型的变量 对象赋值给变量person
Person person = new Person();
System.out.println(person);//com.itheima.oop.Person@1540e19d
//给成员变量person赋值,用set方法
person.setName("张三");
person.setAge(30);
//取出变量的值,用get方法
System.out.println(person.getName());//张三
System.out.println(person.getAge());//30
}
}
构造方法:
方法名字和类型相同,没有返回值。(每一个类都具备。自己不写,也会有默认的无参构造方法;自己写的话,默认就不存在了)
//无参构造方法
public Person() {
}
//有参数构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//创建完毕构造方法后,可以接着创建对象,使用有参的构造
//创建对象,使用有参数的构造
Person person1 = new Person("李四",20);
System.out.println(person1.getName()+person1.getAge());//李四20
-------------------------------------------------------
继承
关键字:extends
/**
* 班主任类
* 直接去使用Person类中的name和age
*/
public class Manager extends Person{
}
/**
* 老师类
*直接去使用Person类中的name和age
* 产生继承关系
* Teacher类去继承Person
*
* 关键字 extends
*
* Teacher extends Person
* 子类(派生类) 父类(超类,基类)
*
*/
public class Teacher extends Person{
}
public class Person {
String name;
int age;
}
public class Test {
public static void main(String[] args) {
//创建对象,Person的子类Teacher对象
Teacher teacher = new Teacher();
//子类对象,调用成员
teacher.age=30;
teacher.name="张三";
System.out.println( teacher.age+"..."+teacher.name);
//同上
Manager manager = new Manager();
manager.age=20;
manager.name="李四";
System.out.println(manager.age+manager.name);
}
}
对于程序,重复内容多,不想做多余的事情(反过来说就是重复的事情,就做一次)
继承的好处:
1.减少代码量,重复的代码,写一次
2.提高维护性
3.类和类直接产生了继承关系—>对象多态特点
弊端:
依赖性,子类依赖父类存在;
代码耦合(以后是要解耦合的)
-------------------------------------------------------
父类中的私有成员(父类的成员使用private修饰)
子类继承父类后,子类会自动拥有父类的成员,注意:不是全部的
此时,子类要想有,就需要父类提供get/set方法,而子类通过get/set方法去使用成员变量
/**
* 定义Person类,人的姓名和年龄
* 私有修饰,本类中使用
*
*
* 继承后,子类会自动拥有父类的成员,注意:不是全部的
* 此时,子类要想有,就需要父类提供get/set方法,而子类通过get/set方法去使用成员变量
*/
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Teacher extends Person{
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.setAge(30);
person.setName("张三");
System.out.println(person.getAge()+person.getName());
}
}
-------------------------------------------------------
继承中子类父类成员变量特点:
1.如果子类自己有,使用自己的(不求人)
2.如果子类自己没有,使用继承过来的(使用父类的)
继承中子类父类成员变量super关键字:
public class Fu {
String str="父类成员";
}
public class Zi extends Fu {
String str="子类成员";
/**
* 定义方法
* this:当前对象,谁调用,就是谁
* 调用本类的成员
* super:表示的是当前类的父类的存储位置
* super关键字,调用父类的成员
*/
public void show(){
String str="方法show";
System.out.println(str);//就近原则
System.out.println(this.str);//this调用本类中的成员
System.out.println(super.str);//super调用父类成员
}
}
/**
* 类继承后,成员变量的特点:
* 1.如果子类自己有,使用自己的(不求人)
* 2.如果子类自己没有,使用继承过来的(使用父类的)
*
*/
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
//zi对象调用成员
//System.out.println(zi.str);//打印的是子类成员
//zi对象调用方法show,打印show里面的sout运行的结果
zi.show();
}
}
-------------------------------------------------------
super内存图:
(普及一下:我们敲的代码是源码,是不能运行的,需要生成class文件,任何程序运行都要进入内存,不进内存是运行不了的)
父类先进入方法去中,子类接着进入方法区;super其实记录的是一个地址,这个地址指向父类;接着main方法进入方法栈(压栈弹栈);再接着成员变量跟随对象在堆内存中存储;
关键:父类中的成员变量,跟随子类对象,进入到堆内存中!!
-------------------------------------------------------
继承后子类父类成员方法的特点:
1.如果子类自己有,使用自己的(不求人)
2.如果子类自己没有,使用继承过来的(使用父类的)
public class Fu {
public void show(){
System.out.println("父类的方法show");
}
}
/**
* 继承后,子类中出现了和父类相同的方法,就称为子类重写了父类的方法。
*/
public class Zi extends Fu {
public void show(){
System.out.println("子类的方法show");
}
}
/**
* 继承后子类父类成员方法的特点:
* 1.如果子类自己有,使用自己的(不求人)
* 2.如果子类自己没有,使用继承过来的(使用父类的)
*/
public class Test {
public static void main(String[] args) {
//创建子类对象
Zi zi = new Zi();
zi.show();
}
}
-------------------------------------------------------
方法的重写(Override):
继承后,子类中出现了和父类相同的方法,就称为子类重写了父类的方法。
注意:有区别与方法的重载(OverLoad):一个类中,方法名字相同,参数列表不同,修饰符和返回值无关。重载是自己的事情,重写是子父类之间的事情,不要混淆。
方法重写的应用(举例:手机案例):
/**
* 手机类
* 定义三个功能:短信,打电话,来电
*/
public class Phone {
//发送短信
public void sendMessage(){
System.out.println("手机发送短信");
}
//打电话
public void call(){
System.out.println("手机发打电话");
}
//来电
public void receive(){
System.out.println("手机来电显示姓名");
System.out.println("手机来电显示号码");
}
}
/*
智能手机
沿袭原有的功能,扩展新功能
继承和方法的重写
发送短信和打电话,无变化,直接使用
对来电进行扩展----方法的重写
*/
public class NewPhone extends Phone{
public void receive(){
// System.out.println("手机来电显示姓名");
// System.out.println("手机来电显示号码");
//调优,父类已经做了,自己不需要在做了
//使用super关键字
super.receive();
System.out.println("显示号码归属地");
System.out.println("显示疑似推销");
}
}
public class Test {
public static void main(String[] args) {
//创建手机对象
Phone phone = new Phone();
phone.sendMessage();
phone.call();
phone.receive();
System.out.println("============");
//创建智能手机的对象
NewPhone newPhone = new NewPhone();
newPhone.sendMessage();//继承
newPhone.call();//继承
newPhone.receive();//重写父类
}
}
-------------------------------------------------------
继承后子类父类构造方法特点:
子类继承父类,子类的构造方法第一行存在隐式代码:super();
super会自动调用父类的无参构造方法;
如果父类中没有无参构造方法,那么子类就需要自己手动添加代码(不添加会报错),super(),然后传递参数,调用父类.
public class Fu {
public Fu(int a){
System.out.println("父类构造方法");
}
}
/**
* 子类继承父类
*
* 子类的构造方法:
* 第一行存在隐式代码:super();
* super调用父类的构造方法;(调用无参构造方法)
*
*/
public class Zi extends Fu {
public Zi(){
//super();//隐式代码
super(1);//父类中没有无参构造方法,自己手动添加并且传参,否则会报错
System.out.println("子类构造方法");
}
}
/**
* 继承后子类父类构造方法特点:
*/
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
}
}
-------------------------------------------------------
继承的特点–单继承:
java技术支持单继承,不能同时继承多个类(一个类只能同时继承一个类,不能同时继承多个类)
继承的特点–多层继承:
java技术支持多层继承,多重继承
例如:class A extends B{} class B extends C{}
-------------------------------------------------------
抽象方法和抽象类定义:
比如我们说的工作,是一种抽象行为,而抽象的行为在程序中又叫做抽象的方法。
定义一个抽象方法:用关键字 abstract
1.抽象方法格式:
权限 抽象 返回值类型 方法名(参数列表);
比如:public abstract void work();
注意:1.抽象方法没有方法主体,不能写{};2.抽象的方法,只能存在于抽象的类中。
2.抽象类格式:
public abstract class Work{}
抽象类的作用:保证继承体系功能的完整性!
/**
* 定义员工类
* 员工的行为:工作
* 这是一种抽象行为,抽象的行为在程序中又叫做抽象的方法
*
* 定义一个抽象方法:
* 用关键字:abstract
*
* 格式:
权限 抽象 返回值类型 方法名(参数列表);
注意:1.抽象方法没有方法主体,不能写{};
2.抽象的方法,只能存在于抽象的类中
*/
public abstract class Employee {//抽象类
//权限 抽象 返回值类型 方法名(参数列表);
public abstract void work();//抽象方法
}
-------------------------------------------------------
抽象类的使用方式:
1.抽象类不能实例化对象(不能new对象,因为没有方法体)
2.创建抽象类的子类,然后继承
3.该子类,必须重写父类的抽象方法
4.创建子类对象(new 子类)
/**
* 定义员工类(抽象类)
* 员工的行为:工作
* 这是一种抽象行为,抽象的行为在程序中又叫做抽象的方法
*
* 定义一个抽象方法:
* 用关键字:abstract
*
* 格式:
权限 抽象 返回值类型 方法名(参数列表);
注意:1.抽象方法没有方法主体,不能写{};
2.抽象的方法,只能存在于抽象的类中
*/
public abstract class Employee {//抽象类
//权限 抽象 返回值类型 方法名(参数列表);
public abstract void work();//抽象方法
}
/**
*
* 老师类,属于员工的一种
* 应该继承员工类,重写抽象方法
*/
public class Teacher extends Employee {
@Override
public void work() {
System.out.println("老师的工作是上课");
}
}
public class Test {
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.work();
}
}
-------------------------------------------------------
抽象类的成员定义:
问题1:抽象类中可以定义成员变量吗?
可以的.继承后,子类可以使用成员变量,前提是父类提供get/set方法,子类再用get/set方法进行赋值.
问题2:抽象类中可以不定义抽象方法吗?
可以不定义.但是依然不能new,不能创建对象.(abstract不能new)
问题3:抽象类中有构造方法吗?
有的.记住,只要是类,就有构造方法