目录
一、面向过程与面向对象
1.面向过程
2.面向对象
3.举例
4.面向对象编程的本质
5.四种权限修饰符
(1)public:公开,任何地方都能使用
(2)protect:在相同的class内部,同一个包内和其他包的子类中能被访问。
(3)default(默认可不写):当前包的所有类都可以访问这个成员
(4)private:除了包含这个成员的类之外,所有类都无法访问这个成员
6.面向对象的三大特性
(1)封装:数据保护(该露的露,该藏的藏)
(2)继承:子承父业,子类会获得父类(也称超类)的所有非私有方法和属性
(3)多态(高拓展性):同一件事不同结果
7、静态方法与非静态方法
(1)静态方法:static修饰的方法,属于类
(2)非静态方法
(3)两者区别
8、引用传递(本质还是值传递)
9.类与对象
10.类的声明
11.对象的创建与初始化
12.this和super的区别
(1)super注意点
(2)this和super的区别
13.重写(需要有继承关系!)
(1)方法名必须相同
(2)参数列表必须相同
(3)修饰符范围:可以扩大但不能缩小(public > protect > default >private)
(4)抛出的异常范围:可以缩小但不能扩大(Exception > 其他异常)
14.向上转型和向下转型
15.static
16.抽象类
17.接口(本质是契约)
18.内部类
(1)成员内部类
(2)静态内部类
(3)局部内部类
(4)匿名内部类
步骤清晰简单,第一步要干什么,第二步要干什么
适合处理较为简单的问题
简单来说就是行为的具体实现,如走:怎么走。
将问题分类,思考问题首先想解决问题需要哪些分类,再根据这些分类进行单独思考,最后在某个分类的细节进行面向过程的处理。
适合处理较为复杂的问题,如多人协作盖房子
人把宠物关进笼子里
面向过程分析:
1.打开笼子
2.将宠物放进笼子
3.关闭笼子
面向对象分析:
1.分析都有哪些实体对象(人,宠物,笼子)
2.为实体对象添加属性和功能
人:打开,关闭笼子,将宠物放进笼子
宠物:能进入笼子
笼子:打开,关闭,存放宠物
3.实现
同面向过程
以类的方式组织代码,以对象组织(封装)数据。
作用:
①提高程序安全性,保护数据
②隐藏实现细节
③统一接口,提高系统维护性
使用:
用private修饰变量/方法
被private修饰的变量/方法不会在其他类中.出来
其他类要想使用该类的属性,需要调用该类提供的公共方法(get,set方法,IDEA快捷键alt + ins)
class Person {
String name;
int age;
//被封装的属性
private double money = 100;
public double getMoney(){
return money;
}
}
使用关键字extends,代表该类是谁的子类(子类是父类的拓展)
在Java中,所有的类都直接或间接继承object类
注意:Java类中只有单继承!
快速查看继承树:ctrl + h
public class Application {
public static void main(String[] args) {
Son son = new Son();
System.out.println(son.name);
System.out.println(son.money);
son.AAA();
}
}
public class Son extends Father {
}
public class Father {
public String name = "w";
double money = 1000000;
public void AAA(){
System.out.println("father的方法");
}
}
前提知识:方法重写(非静态/非私有方法)
//一个对象的实例类型是可以确定的,但其指向的引用类型就不确定了
//如父类的引用指向子类
//能调用的方法都是自己拥有或从父类继承的
Son son1 = new Son();
//父类型,但是不能调用子类独有的方法
Father son2 = new Son();
Object son3 = new Son();
//对象能执行哪些方法,主要看左边的类型!
son1.b();
//一旦子类重写了父类的方法,就会执行子类的方法
son2.b();
son2.c();
public class Father {
public String name = "w";
double money = 1000000;
public void aaa(){
System.out.println("father的方法");
}
public void b(){
System.out.println("father-b");
}
public void c(){
System.out.println("father-c");
}
}
public class Son extends Father {
@Override(注解后面说)
public void b(){
System.out.println("son-b");
}
public void d(){
System.out.println("son-d");
}
}
多态注意点:
①多态是方法的多态,没有属性的多态
条件:
①子类重写了父类方法
②父类引用指向子类对象
判断引用类型间的关系:instanceof
使用方法:
A instanceof B ==》判断A和B是否有关系
写一个Student类
public class Student {
public static void study(){
System.out.println("学生方法");
}
}
再写一个People类,入口写在该类中,调用Student类的study方法
public class People {
public static void main(String[] args) {
Student.study();
}
}
Student类再写一个非静态方法
public class Student {
public void study1(){
System.out.println("学生方法");
}
}
People调用方法,需要实例化
public class People {
public static void main(String[] args) {
//静态调用
Student.study();
//非静态调用,需要
//new Student.study1();
Student student = new Student();
student.study1();
}
}
(1)修饰不同:静态需要static修饰,而非静态则不需要。
(2)时机不同:静态方法在类定义的时候已经被装载和分配,而非静态方法在类定义时并没有创建和加载,只有在类被实例化为对象时,才会装载和分配。这也是为何在静态方法中直接调用非静态方法会报错。
public class Demo01 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
change(person);
System.out.println(person.name);
}
public static void change(Person person){
person.name = "XXX";
}
}
class Person {
String name;
}
类:类是一种抽象的数据类型,它是对某一类事物的整体描述/定义,并不能代表某一个具体的事物
如动物、植物
对象:对象是抽象概念的具体实例
如:张三,张三的狗旺财
类的组成:属性+方法
类的声明:修饰符 + class + 类名{}
类实例化会返回一个对象(具体个体)。
class Person {
//属性
String name;
int age;
//方法
public void walk(){}
public void look(){}
}
使用new关键字创建,本质是在调用构造器
使用new关键字创建的时候,除了分配内存空间外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
构造器:类中的构造器也称构造方法,是在进行创建对象时必须要调用的。
构造器:IDEA快捷键 alt + ins
(1)与类名相同
(2)没有返回类型,不能写void
(3)一个类就算什么也不写,也会存在一个构造方法
作用
(1)实例化初始值
Person person = new Person();
System.out.println(person.name);
//注意,使用有参构造后必须显示定义无参构造(写出无参构造)
Person person1 = new Person("张三");
System.out.println(person1.name);
class Person {
String name;
int age;
//无参构造方法
public Person(){
System.out.println("无参构造");
}
//有参构造方法
public Person(String name){
System.out.println("有参构造");
this.name = name;
}
public void walk(){}
public void look(){}
}
public class Computer {
protected String name = "电脑";
public Computer(){
System.out.println("父类构造执行");
}
public void print(){
System.out.println("输出Computer");
}
}
public class Lenovo extends Computer{
private String name = "联想";
public Lenovo(){
//子类构造会默认执行super();
//super();默认是隐藏在第一行,调用父类构造器必须在第一行
System.out.println("子类构造执行");
}
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
public void test1(){
print();
this.print();
super.print();
}
@Override
public void print(){
System.out.println("输出联想");
}
}
public class Application {
public static void main(String[] args) {
Lenovo computer = new Lenovo();
computer.test("苹果");
lenovo.test1();
}
}
①super调用父类的构造方法,必须在构造方法的第一行
②super只能出现在子类的方法或构造方法中
③super和this不能同时调用构造方法
①对象不同:
this:调用者这个对象
super:代表父类对象的应用
②使用条件
this:没继承也可使用
super:只能在继承条件下使用
③构造方法
this:本类的构造
super:父类的构造
重写的必要性:
父类的功能子类不一定需要/满足
重写:
IDEA快捷键alt + ins -> override
向上:子类转父类
向下:父类转子类(需要强转,可能会丢失方法)
package oop.staticdemo;
//静态导包
import static java.lang.Math.random;
/**
* @author LEGION
*/
public class StaticDemo {
private int num01;
private static int num02;
//代码块(匿名)
{
System.out.println("匿名代码块");
}
//静态代码块,只执行一次
static {
System.out.println("静态代码块");
}
public void A01(){
}
public static void A02(){
}
public static void main(String[] args) {
StaticDemo staticDemo = new StaticDemo();
int num01 = staticDemo.num01;
int num02 = StaticDemo.num02;
staticDemo.A01();
StaticDemo.A02();
A02();
//可以直接random()
System.out.println(random());
}
}
被abstract修饰的类
特点:
①不能new出来,只能靠子类去实现它,主要作用是约束
②抽象类中可以写普通方法
③抽象方法必须在抽象类中
抽象类存在构造器!
/**
* @author LEGION
* abstract修饰的类-抽象类
*/
abstract public class AbstractDemo01 {
/**
* abstract修饰的方法-抽象方法,没有方法的实现
*需要子类实现
*/
abstract public void doSomething();
}
/**
* @author LEGION
* 抽象类的所有方法,继承了它的子类都必须实现它的方法
*/
public class Realize extends AbstractDemo01{
@Override
public void doSomething() {
}
}
抽象类作用:提高开发效率
接口就是规范,专业约束----做到约束与实现的分离
//接口都需要实现类
public interface UserService {
//接口中所有定义都是public abstract
void add();
}
public interface TimeService {
/**
* 接口定义的属性为常量
* public static final long START = 0;
*/
long START = 0;
/**
* 计时
*/
void time();
}
接口的实现:implement关键字
实现接口的类必须实现接口的方法,一个类可以实现多个接口(多实现)
public class UserServiceImpl implements UserService,TimeService{
@Override
public void add() {
}
@Override
public void time() {
}
}
注意:
接口不能实例化,没有构造方法
public class Demo01 {
private int id = 1;
public void out(){
System.out.println("外部类方法");
}
class Inner{
public void inner(){
System.out.println("内部类方法");
}
//获得外部类的私有属性
public int getID(){
return id;
}
}
}
public class Application {
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
demo01.out();
Demo01.Inner inner = demo01.new Inner();
inner.inner();
System.out.println(inner.getID());
}
}
public class Demo01 {
private int id = 1;
public void out(){
System.out.println("外部类方法");
}
class static Inner{
public void inner(){
System.out.println("内部类方法");
}
//获得外部类的私有属性
public int getID(){
return id;
}
}
}
public class Demo01 {
private int id = 1;
public void out(){
System.out.println("外部类方法");
//局部内部类
class Inner{
public void inner(){
System.out.println("内部类方法");
}
//获得外部类的私有属性
public int getID(){
return id;
}
}
}
}
//匿名内部类,不用将实例保存在变量中
new Demo01().out();
new Demo01(){
@Override
public void out(){
}
};