面向对象的思想
用代码模拟现实生活中的事物(类和对象)
– >学生类表示学生事物
先有类还是先有对象?
对象是根据类创建出来的,因此先有类
类
类的创建
1.类名一般大驼峰命名法,每个单词首字母大写
2.一个java文件中可以定义多个类,但是只能有一个类是公共类
注意:public修饰的类名必须与java文件名相同
3.工作中,建议一个java文件只定义一个类
类的组成部分
1.成员变量(事物信息)
2.成员方法(事物方法)
3.构造方法(初始化一个类的对象)
4.内部类
5.代码块
类的创建和使用
new关键字
类名 对象名 = new 类名(参数);
对象对非私有成员调用方式
对象名.成员变量名/成员方法名(参数)
类的构造方法
修饰符 类名(形参){
给成员变量初始值
}
定义构造方法注意事项
没有返回值(连void都没有)
方法名一定和类名相同
构造方法支持重载(同名不同参)
–
此处重载 注意了
与返回值无关 方法名相同 参数列表的个数、类型、顺序不同
面向对象的三大特征
封装 继承 多态
封装
封装思想与作用
思想:隐藏细节,提供公共访问方式
作用:提高代码的安全性/复用性
封装的步骤
先把变量使用private修饰
提供getter、setter方法
快捷键 Alt+insert
构造方法的作用
无参构造:初始化对象数据为默认值
有参构造:初始化对象时,同时为对象数据赋值
/*
类: 对一类具有共同属性和行为事物的描述 (设计图)
对象: 根据类创建出来的实体 (看得见摸得着的实体)
类: 类对对象的描述
对象: 类的实体
怎么样描述对象?
通过类描述对象
通过属性和行为这两方面描述对象
JavaBean
1.成员变量:必须私有
2.构造方法:必须提供两种,无参构造,有参构造
3.成员方法:get和set方法,以及其它方法
*/
public class Student{
//属性-> 成员变量
private String name;
//private修饰的成员变量,只有在本类中
//可以访问,其他可以通过set和get访问
int age;
/*
this知识点
this成员方法中,this指调用该方法的对象
this在构造方法中,当前new出来的对象
解决的问题:
防止局部变量跟成员变量重名问题
*/
//set对私有成员进行赋值
//get对象对私有成员进行访问
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
/*
构造方法:
格式化格式:
public 方法名(){
}
注意事项:
方法名跟类名相同
无返回值
无返回值类型
创建对象时:
类中没有提供构造方法,系统会默认提供一个无参构造
如果类中提供构造方法,系统将不会提供无参构造
*/
//构造方法,创建对象 无参
public Student() {
}
//构造方法,创建对象并且进行赋值 有参
public Student(String name, int age){
this.name = name;
this.age =age;
}
//行为-> 成员方法
public void study(){
System.out.println("学生在学习");
}
public void eat(){
System.out.println("学生在学习");
}
public void show(){
System.out.println("学生个人信息展示"
+ " " + "姓名" + name + "年龄" + age);
}
}
package com.复习;
/*
同包下,建立测试类
*/
public class TestStudent{
public static void main(String[] args){
//创建对象
Student p01 = new Student();
//如果没有构造方法,在创建对象时系统会默认给出空参构造
//访问属性
p01.age = 19;
//p01.name;//因为私有不能被访问,需要加上get,set
p01.study();
System.out.println(p01);//输出地址
System.out.println(p01.age);//0
System.out.println(p01.getName());//null
p01.age = 18;
p01.setName("lvlv");
System.out.println("年龄" + p01.age +
"姓名" + p01.getName());
}
}
匿名对象
什么是匿名对象
没有对象名接受的对象,我们称之为匿名对象
new Student("小吕",18);
有对象的接受的对象,称之为有名对象
Student s1 = new Student("小吕",18);
匿名对象的使用方法
匿名对象可以像有对象一样使用,但是只能使用一次
具体如下:
匿名对象直接调用成员方法
匿名对象直接当作方法参数传递
匿名对象直接当作返回值
继承
什么是继承?
当多个类中有相同的属性和行为时,把这些相同的属性和行为,抽取出来封装到一个单独的类中, 这个类称为父类,多个类都是该类的子类
多个类称为子类(派生类),单独的这个类成为父类(基类或者超类)
Java中的继承使用(extends),来继承这些封装了公共属性和行为的类(父类),继承父类的是子类
继承:有父类,子类
继承的格式:
Public class 子类名 extends 父类名{…}
继承的优点:
提高了代码的复用性(重复代码抽取出来。封装到父类中,子类继承后就可以使用)
提高代码的维护性(父类变动子类也会因此变动)
让类与类之间产生关系,是多态的基础
工作中的规范?
父类中是共性成员,子类特有成员,子类继承父类
为什么子类特有成员不能放到父类?
如果子类的特有成员在父类中定义,会导致父类其他子类也会拥有这些属性和行为,这与java严谨性违背了
例子:学生:姓名 课程名称 所在班级 查看课表 填写反馈数据
老师:姓名 课程名称 部门名称 查看课表 发布成绩
分析:
公共属性:姓名 课程名称 查看课表
其他为特有成员
结果:
父类:姓名 课程名称 查看课表
子类:
学生:所在班级 填写反馈数据
老师:部门名称 发布成绩
继承的特点:
java中的类只支持单继承,不支持多继承,但是可以多层继承
单继承:一个儿子只能有一个爸爸
多层继承:儿子(孙子)继承爸爸,爸爸继承爷爷--->孙子也就间接继承了爷爷
为什么不能多继承?
父类都有相同的属性时,不能区分到底继承谁
this关键字的使用:
//访问本类中的成员变量
this.成员变量=数据值;
//访问本类中的成员方法
this.成员方法();
//访问本类中的构造方法(要求:只能的使用某个构造方法,去调用本类中的另一个构造方法)
public className(){
}
public className (String name){
this();//调用无参构造
}
在使用中的注意事项?
1.Java语言只支持单一继承,不许多继承,但是可以多层次继承
2.子类不能继承父类的私有成员
3.子类和父类存在相同成员时,就近原则
(先找本类,本类没有父类找)
若想要直接调用父类中的该成员,用
super.成员变量
super.成员方法
super(参数1,参数2…)
4.子类对象初始化对象之前,先初始化父类对象,只有父类初始化完成>
后,才能访问父类成员
子类构造方法在执行时,有隐藏代码,super()
//默认调用父类中的无参构造方法
如果父类中没有无参构造方法那就要手动添加带参构造方法
public class Fu {
int num = 10;
public void test01(){
System.out.println("test01");
}
public void test03(){
System.out.println("test03");
}
}
package this_super;
public class Zi extends Fu{
int num = 20;
public void test(){
int num = 30;
System.out.println("局部变量" + num);
System.out.println("当前类成员变量" + this.num);
System.out.println("父类成员变量" + super.num);
}
public void test01(){
System.out.println("test1");
}
public void test02(){
System.out.println("test2");
}
public void show(){
super.test01();
}
}
package this_super;
/*
在子类方法中访问一个变量原则:就近原则
1.先在子类局部范围找
2.然后子类成员找
3.然后父类成员范围找,如果父类范围还没有找到就报错。
注意:父类中私有成员子类不能直接访问
局部变量,本类成员变量,父类成员变量重名如何区分?
1.局部变量直接访问
2.本类成员变量,使用this.本类成员变量
3.父类成员变量,使用super.父类成员变量
继承后成员方法的访问特点是什么样的呢?
子类成员范围找
父类成员范围找
注意:不能直接访问父类中的私有成员
如果子父类出现同名同参数的方法,先使用谁的?如何指定访问父亲的?
如果子父类中,出现了重名的成员方法,会优先使用子类的,要访问父类相同的方法可以使用super关键字,
如:
super.父类成员方法
*/
public class Test01 {
public static void main(String[] args) {
Zi z = new Zi();
z.test();
z.test01();//优先子类调用 就近原则
z.test02();//不冲突 直接访问子类
z.test03();//不冲突 直接访问父类
z.show();
}
}
重写(Override)
什么是重写?
子类和父类出现一摸一样的的方法(方法名,参数列表)
什么时候方法需要重写?
子类需要的功能,父类不能满足需求
沿袭了父类的功能,又定义了子类特有的内容
如何快速重写一个方法?
声明不变,重新实现
重写时方法名和参数列表需要保持一致,对方法体进行重新定义(声明不变,方法体重新实现)
重写注意事项和要求
重写方法的名称和形参列表必须和被重写的方法一致
私有方法不能被重写(因为重新是子类进行的,私有方法不能被子类继承)
子类重写父类方法时,子类方法的访问权限大于或等于父类的方法访问权限
public class Phone {
public int number;
public String message;
public void setMessage(String message) {
this.message = message;
}
public void tellPhone(){
}
public void sendMessage(){
}
}
public class OldPhone extends Phone {
public void tellPhone(){
System.out.println("打电话");
}
public void sendMessage(){
System.out.println("发短信");
}
}
package Override_Overload;
/*案例演示:*/
// 旧手机功能:基本的打电话,发消息
// 新手机功能:基本的打电话下支持视频通话,基本的发消息下支持发送语音和图片
// 定义就手机类,实现打电话,发消息功能,定义新手机继承老手机,重写打电话和发短信功能
public class NewPhone extends OldPhone {
public void tellPhone(){
System.out.println("打视频" );
super.tellPhone();//重写后调用父类中的功能
}
public void sendMessage(){
System.out.println("语音通话"+"图片显示" );
super.sendMessage();
}
}
public class Test {
public static void main(String[] args) {
NewPhone p = new NewPhone();
p.sendMessage();
p.tellPhone();
}
}
package day1_1;
/*
子类中所有的构造方法默认访问父类中的无参构造方法
为什么?
子类在初始化时,有可能会使用父类中的数据,如果父类中没有完全初始化,子类将无法使用父类的数据
子类初始化之前,必须要完成父类初始化
怎么初始化?
构造方法的第一条的默认都是:super()
注意:如果我们编写的类,没有手动指定父类,系统也会自动继承Object(Java继承系统中的最顶层父类)
*/
public class Son extends FATHER{
public Son(){
//隐藏代码super()
this("lvlv");
System.out.println("son的无参");
/*
//调用本类的带参构造方法
public Son(String name){
//隐藏代码super();
super("baby");
}
*/
}
public Son(String name){
//如果父类中没有无参构造方法那就要手动添加带参构造方法
//隐藏代码super();
super("baby");//调用父类的带参构造方法
System.out.println("son的有参");
}
}
/*
this() super()
必须放在构造方法第一行有效语句,并且二者不能共存
通俗易懂,子类构造方法第一句不是super()就是this()
*/
package day1_1;
public class FATHER {
//注意:当father类没有无参构造函数时,子类继承father类时要手动添加带参构造方法
public FATHER(){
System.out.println("FATHER无参构造");
}
public FATHER(String name){
System.out.println("FATHER有参构造");
}
}
package day1_1;
public class superCLASS {
public static void main(String[] args) {
Son S = new Son();
System.out.println(S);
}
}
抽象类
什么是抽象类:
使用abstract关键字修饰的类为抽象类
抽象类格式:
public abstract class 类名{}
什么是抽象方法
使用abstract 关键字修饰且没有具体实现的方法就是一个抽象方法
如何定义?
抽象方法的格式:
public abstract 返回值类型 方法名(参数列表);
普通类跟抽象类区别就是多了个抽象方法
public abstract void 抽象方法();
抽象类的注意事项
抽象类和抽象方法需用abstract关键字修饰
抽象类,不能创建对象(抽象类不能实例化,即就是不能使用new创建对象)
抽象类中可以有抽象方法也可以有非抽象方法
,抽象方法必须存在抽象方法中
抽象类的子类要么重写抽象类中的所有抽象方法,要么子类是一个抽象类
疑问:
既然不能初始化,为什么还有构造方法?
~抽象类通常是用于父类,创建子类对象时,需要先初始化父类
(抽象方法中构造方法的作用就是用于父类初始化使用)
抽象类抽象方法的使用场景?
当父类定义一个方法时,每个子类对该方法的具体实现逻辑都不一样,
那么父类定义该功能时就可以定义成抽象方法,这个类就是抽象类了
抽象类中的抽象方法,必须由子类重写
猫和狗:
共性:动物,吃,喝谁—>父类,因为子类逻辑不同,抽象类
各自成员方法:猫吃鱼,狗吃肉 —>子类方法,抽象类具体实现
public abstract class Animal {
public void drink(){
System.out.println("喝水");
}
public abstract void eat();
}
public class Cat extends Animal {
public void eat(){
System.out.println("猫吃鱼");
}
}
public class Dog extends Animal {
public void eat(){
System.out.println("狗吃肉");
}
}
public class Test01 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.eat();
cat.drink();
System.out.println("---------");
Dog dog = new Dog();
dog.eat();
dog.drink();
System.out.println("---------");
}
}
设计模式
设计模式,就是一种解决方案(解决开发中某个问题的方案)设计模式解决什么问题?
~开发中一些常见的问题,可以使用设计模式解决
模板设计模式:
能够使用抽象类写模板方法设计模式代码
模板:一个固定的格式