目录
1. 面向对象与面向过程
2. 类与对象的关系
3.面向对象思想开发步骤
4.类的定义
5.创建对象
6.属性
7.方法的定义及调用
8.形参与实参
9.方法重载
10.构造器
11.this关键字
12.匿名块
13.包管理
14.继承
15.方法的重写(Override)
16.super关键字
17.多态
18.面向对象类型转换
20.封装——高内聚低耦合
21.修饰符
22.设计模式
23.单例模式
类和对象的关系
- 模板与实例:类是对象的模板,对象是类的引用。
- 数据与行为:类定义了对象的数据结构(即对象的状态)和可以执行的操作(即对象的行为)。
- 创建过程:当根据类创建一个对象时,实际上是分配了一段内存空间,并初始化了类定义的属性值。
- 多态性:不同的对象可以对同一消息做出不同的响应。这意味着同一个方法可以在不同的对象上表现出不同的行为。
- 类是用来描述一类事物共性的抽象概念,而对象则是这一类事物的具体实例。通过类创建对象的过程称为实例化。
找对象 ==》定义类 ==》创建对象 ==》通过对象调用相关行为,完成对应需求
[public] class 类名 {
//属性
//方法
}
类名称 对象名 = new 类名称();
类的属性 也称之为全局变量
[修饰符] 数据类型 属性名 [= 值];
用法:
1.取值
数据类型 变量名 = 对象.属性名;
2.赋值
对象.属性名 = 值;
方法代表一种行为 / 功能 ,当被调用时才会被执行
[修饰符] 返回值类型 方法名(参数列表){
//具体做的事情---方法体;
[return 返回值]
}
高内聚——类的内部,越紧密越好,低耦合——类与类之间没关系才好
- 形式参数 :我们在定义方法的时候使用的参数--本身没有任何实际的意义
- 实际参数 :当我们在调用这个方法的时候传递参数,这个实际参数会传到我们定义方法的参数位置上。实际参数就是给形式参数做赋值的。
- 实际参数----传递值的方式
- by value :按值传递(基本数据类型传值方式)
- by ref :按引用传递
在同一个类中方法名相同,参数列表不同的一组方法被称之为方法的重载
this代表当前对象(谁调用代表谁)
//1.形参名==实参名
this.age =age;
//2.调用方法,几乎不用
this.test02();
test02(); //推荐
//3.this.(); 调用已经存在的构造方法,简化当前的构造方法。
// this() 须写在当前构造方法的第一行
public class Demo {
String name;
int age;
public Demo() {
this.name = name;
}
public Demo(String name, int age) {
this();
this.age = age;
}
}
没有方法名的代码块,在构造方法调用前执行
面向对象小结
Person person1 = new Person(6);
//1.在栈内开辟栈帧,--this产生
//2.调用构造方法,完成属性值的初始化操作
//3.将对象的引用返回person1
import com.oracle.A;//在一个类中使用另外一个包中的类
public class B {
A a;
}
通过现有的类,简化子类的创建(子类就也可以拥有父类的属性和方法)
继承关系:子类(衍生类、派生类) extends 父类
Java中不支持多继承,但可传递继承,一个父类可以有多个子类,一个子类仅有一个父类
所有类会自动继承Object类
在父子类中(至少两个类),子类覆盖父类的方法,要求返回值类型、方法名、参数列表必须与父类保持一致
// 重写object类的toString方法
@Override
public String toString(){
return "Student{"+ "name:"+name+",age:"+age+"}";
}
父类具有的属性和方法,子类可以通过继承拥有,或者通过重写实现选择性继承(同种事务的不同实现方式),子类也可 extends 父类没有的属性和方法
super关键字可以访问父类的成员变量、方法
super.name; super.getname(); super(); //在子类的构造方法中调用父类的构造方法。 此时super关键字出现在构造方法第一位置!!!
子类不可以继承父类的构造方法,但子类的构造方法会先调用父类的构造方法。
this() 和 super()不可以同时出现在同一个构造方法中
在 继承 关系中,父类引用指向子类对象;
多态是同一个行为具有多种不同表现形式的能力,或者是同一个接口,使用不同的实例而执行不同操作
继承、重写、父类引用指向子类对象:Parent p = new Child();
生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
练习(动物吃东西,猫吃鱼):
//父类 动物类
public class Animal {
String name;
int age;
public void eat(){
System.out.println("动物吃东西");
}
public void sleep(){
System.out.println("动物睡觉");
}
}
// 子类: 猫类
public class Cat extends Animal{
String color;
public void eat(){
System.out.println("猫吃鱼");
}
}
//测试类
public class Test {
public static void main(String[] args) {
Animal animal = new Animal();
Cat cat = new Cat();
//父类引用指向子类对象(创建子类对象使用父类类型接收)
Animal a1 = new Cat();//这种就是多态
System.out.println(a1.age);//合法
//System.out.println(a1.color);//不合法
//程序想要运行 需要执行2个过程:1。编译(检查语法) 2。运行(找本质)
a1.eat();//A 猫吃鱼 ---- Cat类中重写了父类Animal中的eat方法,如果不重写,那么就会调用父类中的方法 输出 "动物吃东西"
}
}
动态绑定——父类类型a1调用了eat()方法应该调用的是Animal类中的方法,为什么执行的时候调用的是Cat类中的eat()方法
a1的类型是Animal,所以a1.eat()正常情况下应该调用的是Animal类下的方法。但是Cat类重写了Animal类(父类)中的eat()方法。
在创建子类对象的时候,实现类子类中eat()方法覆盖了父类中的eat()方法。
父类引用a1调用eat()的时候,执行的是子类中的eat(),这个过程就被称之动态绑定
存在于继承关系之间
public class Animal{}
public class Cat extends Animal{}
Animal a = new Cat();
public class Animal{}
public class Cat extends Animal{}
Animal a1 = new Cat();
Animal a2 = new Dog();
a2 = a1;
if(a2 instanceof Cat){
((Cat)a).catchMouse();
}
else if(a2 instanceof Dog){
((Dog)a).loodHome();
}
19.Java抽象类
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类不能被实例化,如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
封装是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。防止该类的代码和数据被外部类定义的代码随机访问。封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
●封装的形式:
○类:封装了属性和方法,属性可以隐藏,通过setter和getter方法进行间接访问
○方法:封装功能代码,实现代码的复用性和扩展性
●访问权限范围修饰符:
private——》default(空)——》protected——》public
修饰符名称 |
同一个类 |
同包 |
不同包,子类 |
不同包,非子类 |
private |
✔ |
|||
default(空) |
✔ |
✔ |
||
protected |
✔ |
✔ |
✔ |
|
public |
✔ |
✔ |
✔ |
✔ |
1.类: -----修饰的类,不能被继承
语法:访问权限范围修饰符 final class 类名{}
2.属性:-----属性不可修改,只能赋值一次,也称常量(字母全部大写)
语法:
3.方法:-------修饰的方法不能被重写
语法:访问权限范围修饰符 final 返回值类型 方法名(参数列表){ 方法体 }
1.类-----静态内部类……
2.属性---静态属性
这个属性是属于类,可以通过 类名.静态属性名 进行访问
3.方法---静态方法
这个方法是属于类,可以通过 类名.静态方法名 进行访问
4.块-----静态块
static{}
static修饰的内容被我们统称为静态成员(静态属性和静态方法以及静态块),生命周期与类相同,只被加载一次(常驻内存),我们不需要创建对象也可以访问
在static修饰的方法中,不能使用this,supper进行修饰
练习:
编写一个程序,输入N个学生数据,包括学号、姓名、成绩,要求输出这些学生数据并计算平均分。
思路:
1.设计一个学生类Stud,包括no(学号)、name(姓名)和deg(成绩)属性,同时包含两个静态变量sum和num,分别存放总分和人数;定义构造方法,用来初始化学号,姓名,成绩,同时记录总人数及总成绩;
2.定义一个静态成员函数avg(),它用于计算平均分。
3.在main()函数中定义了一个对象数组用于存储输入的学生数据。
package com.statics;
import java.util.Scanner;
public class Stud {
static double sum;
static int num;
private String name; //姓名
private int no;
private double deg;
public Stud(String name, int no, double deg, double sum, int num) {
this.name = name;
this.no = no;
this.deg = deg;
Stud.sum += deg;
Stud.num += 1;
}
public static double avg(double sum, int num) {
return sum / num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public double getDeg() {
return deg;
}
public void setDeg(double deg) {
this.deg = deg;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Stud s1[]=new Stud[n];
for(Stud s:s1){
s=new Stud(sc.next(),sc.nextInt(),sc.nextDouble(),sc.nextDouble(),sc.nextInt());
}
System.out.println("平均成绩为:"+avg(sum,num));
}
}
final
必须有初始值的变量、不想被修改的方法,不想被其他类继承的类
static
使用共享数据(一个数据)、使用工具类的时候
1.父类静态代码块
2.子类静态代码块
3.父类非静态代码块
4.父类构造方法
5.子类非静态代码块
6.子类构造方法
解决特定问题的方式方法(套路)-------是前人总结的经验
设计模式一共有23种,大致分为以下三类
1.创建型
2.结构型
3.行为型
如何实现单例模式
1.定义私有化的构造方法
2.定义此类型的static属性
3.提供一个public 静态方法来获取唯一的实例对象,此方法名我们通常叫getInstance
单例设置模式有2种
1。懒汉式
2。饿汉式
public class Sun1 {
private static Sun1 sun = new Sun1();// 饿汉 式
private Sun1(){}
public static Sun1 getInstance(){
return sun;
}
}
public class Test {
public static void main(String[] args) {
Sun1 sun1 = Sun1.getInstance();
Sun1 sun2 = Sun1.getInstance();
Sun1 sun3 = Sun1.getInstance();
System.out.println(sun1);
System.out.println(sun2);
System.out.println(sun3);
}
}