Java基础加强重温_01: 基础回顾(类、对象、类成分、封装、构造方法、this关键字)、static关键字(修饰成员变量,成员方法)、继承( )、抽象类(abstract)、模板设计模式
一、IDAE创建projrct
java:有默认model
Empty project:没有默认model
二、基础回顾
1、什么是类和对象?
类:对同一类事物的抽象(简化、概括…)描述。
对象:类的具体某个实例。 对象==实例
桌子:是一个类 ,这个桌子:是一个对象/实例
猫:是一个类,Tom猫:是一个实例
2、怎么定义类?
public class 类名(首字母大写,遵循驼峰标识) ApplePen
一个java文件可以定义几个类?
无数个class,但是public修饰的类只能有一个,并且与文件名一致。
public class Demo01 { public static void main(String[] args) { //0x001 Student student = new Student("乔碧萝殿下",19,"盛世美颜下的直播"); //获取名字 String name = student.getName(); System.out.println(name); } } //java文件中定义多个类 //在教学情况下用的多,实际工作中基本不用,一个类一个文件 class Dog { } class Cat { }
3、类中的成分
public class 类名 { //1、成员变量(属性、实例变量、类变量...) //2、成员方法(行为、函数、实例方法、类方法...) //3、构造方法(构造器、构造函数、解析函数...) //未来学的 //4、内部类 //5、代码块 }
4、封装
封装是面向对象三大特性之一。(三大特性:抽象、继承、多态)
封装步骤:
1、把成员变量私有化 (使用 private 关键字来修饰成员变量。)
2、提供getter/setter (使用 public 修饰getter和setter方法。)
封装的作用:
1、对于一些私隐可以控制设置和开放
2、可提供代码的逻辑检验(在getter/setter方法中写检验代码)
3、拓展:可以封装方法(组件化)
封装一句话总结:合理隐藏、合理开放
面向对象和面向过程的区别
面向对象/过程:
过程:重头到位实现做饭的过程
1、米(自己去耕田收割)
2、洗米(水龙头怎么接水)
3、煮饭(做电饭煲)
4、盛饭(做碗)
对象:
1、妈妈.public 买米(private 走去市场、private 讨价还价、private 给钱、private 背回来)
2、妈妈.洗米
3、饭煲.做饭
4、自己.盛饭
理解:面向对象即封装方法(或说封装过程),调用方法实现结果,不关注过程,只关注结果
5、构造方法
创建一个学生类,有姓名、年龄、爱好
构造方法的作用:
jvm创建对象,构造方法初始化对象
类名 变量 = new 类名(参数...);
new 类名(参数…), 分两步解析
new: jvm看到new关键字,在堆内存开辟空间,创建对象
类名(参数…): 即构造方法,执行构造方法初始化对象,(无参构造:用系统默认值初始化。有参构造:用传入的参数出初始化)
6、this关键字
this代表所在类的当前对象的引用(地址值),即代表当前对象。
即:构造方法的this,指的是对象本身,谁调用方法this就是谁
1、Student类的对象student调用getNmae()方法
Student student = new Student("乔碧萝殿下",19,"盛世美颜下的直播"); //获取名字, String name = student.getName();
2、在getName()中,加上this,正常返回(一般getter方法,不用加this。)。这个this就是指对像student(谁调用方法this就是谁)
public class Student { // 创建一个学生类,有姓名、年龄、爱好 private String name; private int age; private String hobby; //默认情况下,系统会赠送一个无参的构造方法 public Student(){ } //右键->generate->contructor->选中变量->ok public Student(String name, int age, String hobby) { this.name = name; this.age = age; this.hobby = hobby; } public String getName() { return this.name; //测试加上this。正常返回 } public void setName(String name) { this.name = name; } public int getAge() { return age; //正常getter方法,不用加this。 } ...
this关键字的应用
1、用于普通的gettter与setter方法
2、用于构造器中
构造器即构造方法
三、static关键字
static是静态的意思。 static可以修饰成员变量或者修饰方法。
1、static修饰成员变量 (静态成员变量)
被static修饰的成员是属于类的是放在静态区中,所有的对象【共享】该变量。这个成员变量叫静态成员变量
没有static修饰的成员变量和方法则是属于每个对象的,每个对象都独有的一份。这个成员变量叫实例成员变量
格式:
修饰符 static 数据类型 变量名 = 初始值;
两种成员变量访问对比
静态成员变量的访问
对象.static修饰的成员变量 = xxx;(idea不推荐) 类名.static修饰的成员变量(静态变量) = xxx;
实例变量的访问
对象.实例成员变量
2、static修饰成员方法 (静态成员方法)
有static修饰成员方法,说明这个成员方法是属于类的,这个成员方法称为类方法或者静态方法。
因为类只有一个,所以静态方法在内存区域中也只存在一份,所有的对象都可以共享这个方法。与静态成员变量一样,静态方法也是直接通过类名.方法名称即可访问。
无static修饰的成员方法属于每个对象的, 这个成员方法叫实例方法。
需要注意的是:实例方法是属于每个对象,必须创建类的对象才可以访问。
两种成员变量访问对比
静态成员方法访问
类名.方法名称
实例成员方法访问
对象.实例方法
3、小结:
1.当 static 修饰成员变量或者成员方法时,该变量称为静态变量,该方法称为静态方法。该类的每个对象都共享同一个类的静态变量和静态方法。任何对象都可以更改该静态变量的值或者访问静态方法。但是不推荐这种方式去访
问。因为静态变量或者静态方法直接通过类名访问即可,完全没有必要用对象去访问。
2.无static修饰的成员变量或者成员方法,称为实例变量,实例方法,实例变量和实例方法必须创建类的对象,然后通过对象来访问。
3.static修饰的成员属于类,会存储在静态区,是随着类的加载而加载的,且只加载一次,所以只有一份,节省内
存。存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。它优先于对象存在,所以,可以被所有对象共享。
4.无static修饰的成员,是属于对象,对象有多少个,他们就会出现多少份。所以必须由对象调用
四、继承
就是子类继承父类的属性和行为,使得子类对象可以直接具有与父类相同的属性、相同的行为。子类可以直接
访问父类中的非私有的属性和行为。
理解:继承后,父类中的成员变量和成员方法也有,在子类中不写出来,访问时可以当写出来访问。
继承好处:
- 子类会拥有父类的属性和行为,提高代码的复用性(减少代码冗余,相同代码重复利用)。
- 使类与类之间产生了关系,共同的代码都写在了父类,只需要修改父类就可以应用所有子类,提高代码拓展性。
1、继承的格式
通过 extends 关键字,可以声明一个子类继承另外一个父类
class 父类 { ... } class 子类 extends 父类 { ... }
特点:
1、Java是单继承的,一个类只能继承一个直接父类。
// 一个类只能有一个父类,不可以有多个父类。 class A {} class B {} class C extends A {} // ok // class C extends A, B {} // error
2、一个类可以有多个子类。
// A可以有多个子类 class A {} class C1 extends A {} class C2 extends A {}
3、可以多层继承。
class A {} class B extends A {} class C extends B {}
Object类是所有类的父类: 顶层父类是Object类。所有的类默认继承Object,作为父类。
继承练习案例
请使用继承定义以下类:
- 学生类 属性:姓名,年龄 行为:吃饭,睡觉
- 老师类 属性:姓名,年龄,薪水 行为:吃饭,睡觉,教书
- 班主任 属性:姓名,年龄,薪水 行为:吃饭,睡觉,管理
案例分析
老师类,学生类,还有班主任类,实际上都是属于人类的,我们可以定义一个人类,把他们相同的属性和行为都定义。在人类中,然后继承人类即可,子类特有的属性和行为就定义在子类中了。
代码实现:
父类Human类
public class Human { // 合理隐藏 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; } }
子类Teacher类
public class Teacher extends Human { // 工资 private double salary ; // 特有方法 public void teach(){ System.out.println("老师在认真教技术!"); } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } }
子类Student类
public class Student extends Human{ }
子类BanZhuren类
public class Teacher extends Human { // 工资 private double salary ; // 特有方法 public void admin(){ System.out.println("班主任强调纪律问题!"); } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } }
测试类
public class Test { public static void main(String[] args) { Teacher dlei = new Teacher(); dlei.setName("播仔"); dlei.setAge("31"); dlei.setSalary(1000.99); System.out.println(dlei.getName()); System.out.println(dlei.getAge()); System.out.println(dlei.getSalary()); dlei.teach(); BanZhuRen linTao = new BanZhuRen(); linTao.setName("灵涛"); linTao.setAge("28"); linTao.setSalary(1000.99); System.out.println(linTao.getName()); System.out.println(linTao.getAge()); System.out.println(linTao.getSalary()); linTao.admin(); Student xugan = new Student(); xugan.setName("播仔"); xugan.setAge("31"); //xugan.setSalary(1000.99); // xugan没有薪水属性,报错! System.out.println(xugan.getName()); System.out.println(xugan.getAge()); } }
2、子类不能继承的内容
1、父类private的属性和行为无法被子类【使用】,父类私有的属性和行为被子类继承(储存)
子类可以继承父类的私有成员(成员变量,方法),只是子类无法直接访问而已。
父类的private成员变量,子类可以通过getter/setter方法访问。
2、构造方法:子类不能继承父类的构造器,因为子类有自己的构造器。因为构造方法必须与类名一致,父类的不可能与子类一致,所以不能被继承
拓展:
3、父类静态的方法和变量也可以被继承
3、 继承后构造器的特点,this和super引用构造方法:this()和super()
当类之间产生了关系,其中各类中的构造器,又产生了哪些影响呢? 首先我们要回忆两个事情,构造器的定义格式和作用。
- 构造器的名字是与类名一致的。所以子类是无法继承父类构造方法的。
- 构造器的作用是初始化对象成员变量数据的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。(先有爸爸,才能有儿子)继承后子类构造器特点:子类所有构造器的第一行都会先调用父类的无参构造器,再执行自己
super()
每个子类构造方法默认都隐藏了一句话:super(),该方法指的是父类的构造方法
public class Person { ... }
public class Student extends Person{ ... public Student(){ // super(); //父类的构造方法 System.out.println("儿子的构造方法"); } ... }
当一个子类对象被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象的外部放上子类独有的属性,这个两者结合起来形成了一个子类的对象。子类是拥有父类的私有属性和方法,但无法直接使用。
super()调用的时父类无参构造方法,super(参数…) 输入参数后调用的是父类有参构造方法
运行原理
父类空间优先于子类对象产生
在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空
间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造器调用时,一定先调用父类的构造器。
this()
this()指的是子类的构造方法,可以理解为本类的构造方法
在子类有参构造方法调用子类无参构造,在new子类对象时执行有参构造和无参构造
public class Student extends Person{ ... public Student(){ System.out.println("儿子的构造方法"); } public Student(String name,int age){ this(); //添加this() System.out.println("儿子的构造方法"); } ... }
注意
1、this()与super(): this(),super()必须要放在第一句
- 对于父类非私有的变量,super存在的价值是:解决子类无法通过this/super直接访问父类的私有变量,设计者为了统一,父类的变量初始化统一放到了父类构造方法中
- super()为什么要放第一句:如果不是第一句意味着可以this/super去调用父类的变量,而这个时候父类的变量还没初始化。
2、this()和super()不能共存,否则编译异常,只能选择其中之一。本质第一句永远都是super(参数…)
小结:
this和super三大作用:调用属性、调用方法、利用this表示当前对象。
//调用属性 this.成员变量 -- 本类的 super.成员变量 -- 父类的 //调用方法 this.成员方法名() -- 本类的 super.成员方法名() -- 父类的 //指代构造方法 super(...) -- 调用父类的构造器,根据参数匹配确认有参/无参 this(...) -- 调用本类的其他构造器,根据参数匹配确认有参/无参
this()与super()使用详解:https://blog.csdn.net/lncsdn_123/article/details/79025525
4、继承后子类成员变量和成员方法的特点
成员变量
1、子类、父类成员变量不重名:正常访问是没有影响
2、子类、父类成员变量重名
子类会优先访问自己对象中的成员变量。此时想访问父类成员变量需要使用super关键字。super代表的是父类对象的引用,this代表的是当前对象的引用。
super.父类成员变量名
成员方法
1、成员方法不重名:访问没有影响
对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。
2、成员方法重名:创建子类对象调用该方法的时候,子类对象会优先调用自己的方法。
this和super的区别
this 能获取本类、父类有权限的属性和行为,能用在任意类中
super 只能调用父类的有权限的属性和行为,super只能用在子类中
理解:子类继承父类有权限的属性和行为,这些权限和行为等于子类的权限和行为,在本类用this获取当然可以
5、方法重写
子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也
称为重写或者复写。声明不变,重新实现。
区分:
方法重载: 同一个类中相同方法名,不同参数类型(两同一不同)
继承的情况下:子类定义与父类同名的方法
1、同名同参同返回值:方法重写,不会报错
2、同名同参不同返回值:报错(二义性问题)
二义性:同名同参的方法在一个类中出现了多个
3、同名同返回值不同参:不报错,等于方法重载
理解:子类继承了父类方法,又在子类定义跟父类同名不同返回值的方法,等于一个类定义两个相同名字不同返回值的方法,因此产生二义性,不知道执行哪个。
应用场景:
认为父类的方法不能满足子类使用,可以进行方法重写。
方法重写案例
定义了一个动物类
public class Animal { public void run(){ System.out.println("动物跑的很快!"); } public void cry(){ System.out.println("动物都可以叫~~~"); } }
定义一个猫类,猫认为父类cry()方法不能满足自己的需求
public class Cat extends Animal { public void cry(){ System.out.println("我们一起学猫叫,喵喵喵!喵的非常好听!"); } }
测试
public class Test { public static void main(String[] args) { // 创建子类对象 Cat ddm = new Cat(); // 调用父类继承而来的方法 ddm.run(); // 调用子类重写的方法 ddm.cry(); }
方法重写注意事项
- 方法重写是发生在子父类之间的关系。
- 子类方法覆盖父类方法,必须要保证权限大于>=父类权限。
- 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。
- 父类private修饰的方法无法被重写
public > protected > 缺省
@Override重写注解
- @Override:注解,重写注解校验!
- 这个注解标记的方法,就说明这个方法必须是重写父类的方法,否则编译阶段报错。
- 建议重写都加上这个注解,一方面可以提高代码的可读性,一方面可以防止重写出错!
public class Cat extends Animal { @Override public void cry(){ System.out.println("我们一起学猫叫,喵喵喵!喵的非常好听!"); } }
五、抽象类
父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了(因为子类对象会调用自己重写的方法)。换句话说,父类可能知道子类应该有哪个功能,但是功能具体怎么实现父类是不清楚的(由子类自己决定),父类完全只需要提供一个没有方法体的方法签名即可,具体实现交给子类自己去实现。
我们把没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类。
- 抽象方法 : 没有方法体的方法。
- 抽象类: 包含抽象方法的类。
abstract关键字
abstract是抽象的意思,用于修饰方法方法和类。abstract修饰的方法是抽象方法,abstract修饰的类是抽象类。
1、abstract修饰类-抽象类
如果一个类包含抽象方法,那么该类必须是抽象类。注意:抽象类不一定有抽象方法,但是有抽象方法的类必须定义成抽象类。
//抽象类定义格式 abstract class 类名字 { }
代码举例:
public abstract class Animal { public abstract void run();}
抽象类存在的意义是为了被子类继承,否则抽象类将毫无意义。抽象类体现的是模板思想,模板就是通用的东西。抽象类已经是具体的实现(抽象类中可以有成员变量和实现方法),而将模板中不能决定的东西定义成抽象方法,让使用模板(继承抽象类的类)的类去重写抽象方法实现需求,这是典型的模板思想。
抽象类和普通类的区别:
- 1、抽象类能定义抽象方法,普通类不允许定义抽象方法(如果普通类有抽象方法也变成抽象类)
- 2、抽象类不能创建对象,普通类可以创建对象。
没有方法体的抽象方法是不能被调用的,而抽象类中可以定义抽象方法,如果可以创建对象,就可以调用没有方法体的抽象方法。
小结:
抽象类的特征总结起来可以说是 有得有失
有得:抽象类得到了拥有抽象方法的能力。
有失:抽象类失去了创建对象的能力。
其他成员(构造器,实例方法,静态方法等)抽象类都是具备的。
2、abstract修饰方法-抽象方法
使用 abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。
//抽象方法定义格式 修饰符 abstract 返回值类型 方法名 (参数列表);
代码举例:
public abstract void run();
特点:
- 1、必须要被子类重写,体现的是约束作用(约束子类必须重写父类全部的抽象方法)
子类不重写全部的抽象方法?子类如果不全部重写父类的抽象方法,那子类依然是抽象类 - 2、抽象方法必须在抽象类内
抽象方法与普通方法的区别:
1、普通方法必须要有方法体,抽象必须没有方法体。(没有方法体即没有{})
2、普通方法结尾不需要加;,抽象方法必须结尾加; (理解:把 {}换成;)
//普通方法 public void work() { } //抽象方法 public void work();
定义抽象方法不能和哪些关键字共存:
- 1、private
私有的方法无法被子类重写,abstract的方法必须要被子类重写才有意义
- 2、static
静态的方法属于当前类,类.静态方法,abstract的方法没有方法体,不能直接调用
- 3、final
final是最终的意思。final修饰的类不能被继承。同理,被修饰的方法也不能进行修改。 一句话概述:final修饰的东西不能被修改,不能被继承。abstract的意义是为了让子类实现方法而存在,而final的意义是不让子类进行修改,它们是处于一个互斥的意义。当二者同时修饰于一种东西(无论是类,还是方法)上,则会报错
3、总结
关于抽象类的使用,以下为语法上要注意的细节,虽然条目较多,但若理解了抽象的本质,无需死记硬背。
- 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。 - 抽象类中,可以有构造器,是供子类创建对象时,初始化父类成员使用的。
理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。 - 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设
计。 - 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则子类也必须定义成抽象类,编译无法通过而报错。
理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意
义。 - 抽象类存在的意义是为了被子类继承,抽象类体现的是模板思想。
理解:抽象类中已经实现的是模板中确定的成员,抽象类不确定如何实现的定义成抽象方法,交给具体的
子类去实现。
六、抽象类的应用——模板设计模式
设计模式
java一共有23种设计模式,设计模式其实就是开发的套路。
什么是模板
做月饼 先做一个模子,丢进去的做月饼的材料是能变的。把固定的东西确定下来,变化的东西根据实际情况修改就是模板。
我们现在使用抽象类设计一个模板模式的应用,例如在小学的时候,我们经常写作文,通常都是有模板可以套用的。假如我现在需要定义新司机和老司机类,新司机和老司机都有开车功能,开车的步骤都一样,只是驾驶时的姿势有点不同, 新司机:开门,点火,双手紧握方向盘,刹车,熄火 , 老司机:开门,点火,右手握方向盘左手抽烟,刹车,熄火 。我们可以将固定流程写到父类中,不同的地方就定义成抽象方法,让不同的子类去重写。
代码实现
司机开车的模板类
public abstract class Driver { public void go() { System.out.println("开门"); System.out.println("点火"); // 开车姿势不确定?定义为抽象方法 ziShi(); System.out.println("刹车"); System.out.println("熄火"); } public abstract void ziShi(); }
定义两个使用模板的司机
public class NewDriver extends Driver { @Override public void ziShi() { System.out.println("新司机双手紧握方向盘"); } } public class OldDriver extends Driver { @Override public void ziShi() { System.out.println("老司机右手握方向盘左手抽烟..."); } }
测试类
public class Demo02 { public static void main(String[] args) { NewDriver nd = new NewDriver(); nd.go(); OldDriver od = new OldDriver(); od.go(); } }
运行效果:
- 点赞
- 收藏
- 分享
- 文章举报
- java的方法重载,面向对象的概念,编写类以及创建对象,成员变量与局部变量的区别,构造方法以及构造方法的重载,空指针异常,封装,this关键字,参数传递,static关键字,继承的概念及相关代码
- Java基础加强重温_02:接口(成分:抽象方法、常量、默认方法、静态方法、私有方法,实现、继承)、final关键字(修饰类、方法)、单例设计模式(懒汉、饿汉)、枚举(底层原理、编译与反编译)
- Java基础第7天+成员变量和局部变量的区别、匿名对象、封装、private关键字、this关键字、构造方法、static关键字...
- java基础七(成员变量 局部变量 匿名对象 封装 设计原则 private this 构造方法 static)
- JAVA基础初探(三)面向对象思想、类与对象、成员变量与局部变量、构造方法、static关键字详解
- 成员变量和局部变量的区别、方法的形参为类的情况及匿名对象、封装(private关键字)、this关键字、构造方法、static关键字
- java面向对象总结(三)继承【This和Super、覆盖(复写,重写)、final、抽象类: abstract、模板方法设计模式】
- 7 面向对象(成员变量和局部变量的区别,类作为形式参数的问题,匿名对象,封装,private关键字,this关键字,构造方法,类的初始化过程,static关键字)
- Java基础——继承+子父类相关特点+Final关键字+抽象类+模板方法设计模式+接口
- 黑马程序员_Java基础_面向对象(概述、类与对象关系、成员变量、封装private、构造函数和构造代码块、this关键字)
- 黑马程序员—Java面向对象(类和对象、封装、构造方法、this关键字、static关键字)
- 匿名对象、封装的概述;关键字(private,this,static)的概述和应用;成员变量和静态变量的区别;如何使用JDK提供的帮助文档;Math类的随机数使用功能;构造方法的概述和格式
- Java面向对象三大特性之(封装和继承)以及抽象类、模板设计模式、final关键字
- 黑马程序员_Java基础_面向对象(继承、子父类变量和函数以及构造函数特点、final关键字、抽象类、模版方法模式、接口)
- 黑马程序员---java基础---面向对象中的构造方法及static关键字,变量的问题
- 重踏学习Java路上_Day07(成员与局部变量,形参,匿名对象,封装,private,this,构造与成员方法,static)
- Java基础-07.总结private,this,封装,static,成员方法变量,局部变量匿名对象
- Java中类的继承,属性和方法的四种修饰符的作用范围,final关键字,java的三大特点中的2个:封装和多态,以及多态的一个设计模式,模板方法模式(template method)
- Java基础-07.总结private,this,封装,static,成员方法变量,局部变量匿名对象
- JAVA基础知识点汇总【入门程序、常量、变量、数据类型转换、运算符、方法入门、流程控制语句、IDEA、方法、数组、类与对象、封装、构造方法】