面向过程思想java
面向对象思想编程
对于描述复杂的事物,为了从宏观上把握,从整理上合理分析,咱们须要使用面向对象的思路来分析整个系统。可是,具体到微观操做,仍然须要面向过程去处理。安全
面向对象编程(Object-Oriented Programming,OOP)dom
面向对象编程的本质是:以类的方式组织代码,以对象的组织(封装)数据ide
抽象oop
三大特性:学习
从认识角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象测试
从代码运行角度考虑是先有类后有对象。类是对象的模板。this
1.该露的露,该藏的藏设计
2.封装(数据的隐藏)
⭐️属性私有,get/set
Student类
package com.oop.demo04; //类 private:私有 public class Student { //属性私有 private String name;//名字 private int id;//学号 private char sex;//性别 private int age;//年龄 //提供一些能够操做这个属性的方法 //提供一些public的get、set的方法 //get得到这个数据 public String getName(){ return this.name; } //set给这个数据设置值 public void setName(String name){ this.name = name; } //alt+insert 自动生成get、set方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { if(age>120 || age<0){ this.age=3; }else{ this.age = age; } } /* 1.提升程序的安全性,保护数据 2.隐藏代码的实现细节 3.统一接口 4.系统可维护性增长了 */ }
测试类
package com.oop; import com.oop.demo03.Pet; import com.oop.demo04.Student; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { Student s1 = new Student(); s1.setName("沈小榆"); System.out.println(s1.getName());//沈小榆 s1.setAge(999);//不合法的 3 System.out.println(s1.getAge());//3 } }
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
extands的意思是“扩展”。子类是父类的扩展
Java中类只有单继承,没有多继承:一个儿子只有一个爸爸,一个爸爸能够有多个儿子
继承是类和类之间的一种关系。除此以外,类和类之间的关系还有依赖、组合、聚合等
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
子类和父类之间,从意义上讲应该具备“is a”的关系
object 类:在java中全部的类,都默认直接或者间接继承Object
super注意点:
super和this对比
表明的对象不一样:
前提:
构造方法的区别:
父类Person类
package com.oop.demo05; //在java中全部的类,都默认直接或者间接继承Object //Person 人:父类 public class Person /*extends Object*/{ private int money =10_0000_0000; protected String name ="shenxiaoyu"; public void say(){ System.out.println("Person"); } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } public Person() { System.out.println("Person无参执行了"); } }
子类Student类
package com.oop.demo05; //Student is Person 学生是人 //子类继承了父类就会拥有父类的所有方法,私有的东西没法被继承 public class Student extends Person { //ctrl+H能够查看继承树 private String name ="moguyu"; public void test1(String name){ System.out.println(name); System.out.println(this.name); System.out.println(super.name); } public void say(){ System.out.println("Student"); } public void test2(){ say();//Student this.say();//Student super.say();//Person } public Student() { //隐藏代码:调用了父类的无参构造 super();//调用父类的构造器,必需要在子类构造器的第一行 //this()调用本身的构造器也须要放在代码的第一行 System.out.println("Student无参执行了"); } }
测试类
package com.oop; import com.oop.demo03.Pet; import com.oop.demo05.Person; import com.oop.demo05.Student; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { Student student = new Student(); /* Person无参执行了 Student无参执行了 */ student.say(); student.test1("沈小榆"); /* 沈小榆 moguyu shenxiaoyu */ student.test2(); } }
须要有继承关系,子类重写父类的方法
重写,子类的方法和父类必须保持一致:方法体不一样!
static方法,属于类,它不属于实例,不能被重写
final 常量,被final修饰的也不能重写 类若是被final,则他不能被继承--->final以后断子绝孙
private方法,私有,也不能重写
重写的意义:
Alt+Insert:override
父类B类
package com.oop.demo05; //重写都是方法的重写,和属性无关 public class B { public void test1(){ System.out.println("B=>test()"); } public static void test2() { System.out.println("B=>test()"); } }
子类A类
package com.oop.demo05; //继承 public class A extends B{ @Override//注解:有功能的注解 //Override 重写 public void test1() { System.out.println("A=>test()"); } public static void test2() { System.out.println("A=>test()"); } }
测试类
package com.oop; import com.oop.demo05.A; import com.oop.demo05.B; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { //静态方法的和非静态方法区别很大 //静态方法:方法的调用只和左边,定义的数据类型有关 //重写只和非静态方法有关 A a = new A(); a.test1();//A=>test() a.test2();//A=>test() //父类的引用指向了子类 B b = new A(); b.test1();//A=>test() 子类重写了父类的方法 b.test2();//B=>test() } }
即同一方法能够根据发送对象的不一样而采用多种不一样的行为方式
一个对象的实际类型是肯定的,但能够指向对象的引用的类型有不少
多态存在的条件
注意:
父类Person类
package com.oop.demo06; public class Person { public void run(){ System.out.println("run"); } }
子类Student类
package com.oop.demo06; public class Student extends Person{ @Override public void run() { System.out.println("son"); } public void eat(){ System.out.println("eat"); } }
测试类
package com.oop; import com.oop.demo06.Person; import com.oop.demo06.Student; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { //Student student = new Student(); //new Person(); //一个对象的实际类型是肯定的 //能够指向的引用类型就不肯定了:父类的引用指向子类 //Student 能调用的方法都是本身的或者父类的! Student s1 = new Student(); //Person 父类型,能够指向子类,可是不能调用子类独有的方法 Person s2 = new Student(); Object s3 = new Student(); //对象能执行哪些方法,主要看对象的类型和右边关系不大 s2.run();//son 子类重写了父类的方法,执行了子类的方法 s1.run();//son s1.eat(); } }
instanceof:用来查看能不能经过编译
package com.oop; import com.oop.demo06.Person; import com.oop.demo06.Student; import com.oop.demo06.Teacher; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { //Object>person>Student //Object>person>Teacher Object object = new Student(); //System.out.println(X instanceof Y);能不能编译经过 System.out.println(object instanceof Student);//true System.out.println(object instanceof Person);//true System.out.println(object instanceof Object);//true System.out.println(object instanceof Teacher);//false System.out.println(object instanceof String);//false System.out.println("==================================="); Person person = new Student(); System.out.println(person instanceof Student);//true System.out.println(person instanceof Person);//true System.out.println(person instanceof Object);//true System.out.println(person instanceof Teacher);//false //System.out.println(person instanceof String);编译报错 System.out.println("==================================="); Student student = new Student(); System.out.println(person instanceof Student);//true System.out.println(person instanceof Person);//true System.out.println(person instanceof Object);//true //System.out.println(person instanceof Teacher);编译报错 //System.out.println(person instanceof String);编译报错 } }
类型转化
子类Student类
package com.oop.demo06; public class Student extends Person{ public void go(){ System.out.println("go"); } }
测试类
package com.oop; import com.oop.demo06.Person; import com.oop.demo06.Student; import com.oop.demo06.Teacher; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { //类型之间的转化:父类 子类 //高 ------->低 须要强制转换 Person obj = new Student(); //student将这个对象转换为Student类型,咱们就可使用Student类型的方法了 Student student = (Student) obj; student.go();//((Student) obj).go(); Person person = student; } }
修饰符和返回类型
package com.oop.demo01; //Demo01 类 public class Demo01 { //main方法 public static void main(String[] args) { } /* 修饰符 返回值类型 方法名(...){ //方法体 return 返回值; } */ public String sayHello(){ return "hello,world!"; } public void hello(){ return; } public int max(int a,int b){ return a>b ? a : b;//三元运算符 } }
break和return区别
方法名:注意规范!见名知意
参数列表:(参数类型,参数名)....
异常抛出
静态方法和非静态方法
Demo02类
package com.oop.demo01; public class Demo02 { public static void main(String[] args) { Student.say(); //实例化这个类 new //对象类型 对象名 = 对象值 Student student = new Student(); student.said(); } }
Student类
package com.oop.demo01; //学生类 public class Student { //静态方法 static public static void say(){ System.out.println("学生说话了"); } //非静态方法 public void said(){ System.out.println("学生说过话了"); } }
static方法和static方法能相互调用,非静态方法和非静态方法能相互调用。非静态方法里能够直接调用静态方法,可是,静态方法里不能直接调用非静态方法:
//和类一块儿加载的 public static void a(){ b(); //不能直接调用c()和d() } public static void b(){ a(); //不能直接调用c()和d() } //类实例化以后才存在 public void c(){ a(); b(); d(); } public void d(){ a(); b(); c(); }
形参和实参
package com.oop.demo01; public class Demo03 { public static void main(String[] args) { //形式参数和实际参数的类型要对应 Demo03 demo03 = new Demo03(); int add = demo03.add(1,2);//实际参数 System.out.println(add); } public int add(int a,int b){//形式参数 return a+b; } }
值传递和引用传递
值传递:
package com.oop.demo01; //值传递 public class Demo04 { public static void main(String[] args) { int a = 1; System.out.println(a);//1 Demo04.change(a); System.out.println(a);//1 } //返回值为空 public static void change(int a){ a=10; } }
引用传递:
package com.oop.demo01; //引用传递 public class Demo05 { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name);//油炸蘑菇鱼 Demo05.change(person); System.out.println(person.name);//沈小榆 } public static void change(Person person){ //person是一个对象:指向的----> Person person =new Person(); 这是一个具体的人,能够改变属性! person.name = "沈小榆"; } } //定义了一个Person类,有一个属性:name class Person{ String name="油炸蘑菇鱼"; }
this关键字
类是一种抽象的数据类型,它是对某一类事物总体描述/定义,可是并不能表明某一个具体的事物
对象是抽象概念的具体实例
使用new关键字建立对象
使用new关键字建立的时候,除了分配的内存空间以外,还会给建立好的对象进行默认的初始化以及类中构造器的调用
Student类:
package com.oop.demo02; //学生类 public class Student { //属性:字段 String name; int age; //方法 public void study(){ System.out.println(this.name+"在学习"); } }
Application类:
package com.oop.demo02; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { //类:抽象的,须要实例化 //类实例化后会返回一个本身的对象 //xiaoyu对象就是一个Student类的具体实例 Student xiaoyu = new Student(); Student xiaofu = new Student(); xiaoyu.name="鱼鱼"; xiaoyu.age=6; xiaofu.name="付付"; xiaofu.age=9; System.out.println(xiaoyu.name);//鱼鱼 System.out.println(xiaoyu.age);//6 System.out.println(xiaofu.name);//付付 System.out.println(xiaofu.age);//9 } }
构造器详解
类中构造器也称为构造方法,是在进行建立对象的时候必需要调用的。而且构造器有如下两个特色:
public class Person { public Person() { } }
构造器做用:
注意点:
Person类
package com.oop.demo02; //java---> class public class Person { //一个类即便什么都不写,它也会存在一个方法,这个方法就是构造方法 //显示的定义构造器 String name; //实例化初始值 //1.使用new关键字,本质是在调用构造器 //2.用来初始化值 public Person(){ this.name="小鱼鱼";//this.是当前的值,=后面是构造器传进来的值 } //有参构造:一旦定义有参构造,无参构造必须显示定义 public Person(String name){ this.name=name; } //Alt+Inset会生成构造器 constructor--->--->0k---->有参 //Alt+Inset会生成构造器 constructor--->--->select none---->无参 }
测试类
package com.oop.demo02; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { //new实例化了一个对象 Person person = new Person(); Person person1 = new Person("XIAOYUYU"); System.out.println(person.name);//小鱼鱼 System.out.println(person1.name);//XIAOYUYU } }
Pet类
package com.oop.demo03; public class Pet { public String name;//public能够在不在一个包的时候也能调用 public int age; //无参构造 public void shout(){ System.out.println("叫了一声"); } }
Application类
package com.oop; import com.oop.demo03.Pet; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { Pet dog = new Pet(); dog.name ="火锅"; dog.age=3; System.out.println(dog.name); System.out.println(dog.age); Pet cat = new Pet(); } }
内存分析图片:
类与对象
对象的属性:字段field 成员变量
默认初始化:
数字:0 0.0
char:u0000
oolean:false
引用:null
定义:
对象的建立和使用
类里有
package com.oop.demo07; //static public class Student { private static int age;//静态变量 private double score;//非静态变量 public void run(){ } public static void go(){ } public static void main(String[] args) { Student s1 = new Student(); System.out.println(age); //System.out.println(Student.score);非静态变量不能直接调用 System.out.println(s1.age); System.out.println(s1.score); go(); s1.run(); } }
package com.oop.demo07; public class Person { /* { //代码块(匿名代码块) } static{ //静态代码块 } */ //2:赋初始值 { System.out.println("匿名代码块"); } //1 只执行一次 static{ System.out.println("静态代码块"); } //3 public Person() { System.out.println("构造方法"); } public static void main(String[] args) { Person p1 = new Person(); /* 静态代码块 匿名代码块 构造方法 */ System.out.println("============="); Person p2 = new Person(); /* 匿名代码块 构造方法 */ } }
package com.oop.demo07; import static java.lang.Math.random;//静态导入包 import static java.lang.Math.PI; public class Test { public static void main(String[] args) { System.out.println(random()); System.out.println(PI); } }
abstract修饰符能够用来修饰方法也能够修饰类,那么该方法就是抽象方法;若是修饰类,那么该类就是抽象类
抽象类中能够没有抽象方法,可是有抽象方法的类必定要声明为抽象类
抽象类,不能使用new关键字来建立对象,它是用来让子类继承的
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的
父类Action类
package com.oop.demo08; //abstract 抽象类 extends 单继承 接口能够多继承 public abstract class Action { //约束——有人帮咱们实现 //abstract,抽象方法,只有方法名字,没有方法的实现 public abstract void doSomething();//有抽象方法必定要声明抽象类 //1.不能new这个抽象类,只能靠子类去实现它:约束! //2.抽象类中能够写普通方法 //3.抽象方法必须写在抽象类中 }
子类A类
package com.oop.demo08; //抽象类的全部方法,继承了他的子类,都必需要实现他的方法,除非子类也是abstract public class A extends Action{ @Override public void doSomething() { } }
子类继承抽象类,那么就必需要实现抽象类没有实现的抽象方法,不然该子类也要声明为抽象类
抽象类存在的意义:提升开发效率
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有
接口:只有规范!本身没法写方法!约束和实现分离!
接口就是规范,定义的是一组规则,体现了现实世界中“若是你是...则必须能...”的思想。若是你是天使,则必须能飞。
接口的本质就是契约,就像咱们人间的法律同样。制定好后你们都遵照
OO的精髓就是对对象的抽象,最能体现这一点的就是接口。
声明类的关键字是class,声明接口的关键字是interface
UserService接口:
package com.oop.demo09; //interface 定义的关键字,接口都须要有实现类 public interface UserService { //接口中全部的属性是 public static final int AEG = 99; //接口中全部的定义的方法其实都是抽象的 public abstract void add(String name); void delete(String name); void update(String name); void query(String name); }
TimeService接口:
package com.oop.demo09; public interface TimeService { void timer(); }
UserServiceImpl类用来实现接口:通常命名为接口名+Impl
package com.oop.demo09; //抽象类: extends //类能够实现接口 implements 接口 //实现了接口的类,就须要重写接口的方法 //利用接口实现多继承 public class UserServiceImpl implements UserService,TimeService{ @Override public void add(String name) { } @Override public void delete(String name) { } @Override public void update(String name) { } @Override public void query(String name) { } @Override public void timer() { } }
接口的做用:
内部类就是在一个类内部定义一个类。好比,A类中定义一个B类,那么B类就是A类的内部类,A类就是B类的外部类
Outer类:内部类能够得到外部类的私有属性
package com.oop.demo10; public class Outer { private int id=10; public void out(){ System.out.println("这是外部类的方法"); } public class Inner{ public void in(){ System.out.println("这是内部类的方法"); } //得到外部类的私有属性 public void getID(){ System.out.println(id); } } public void method(){ //局部内部类 class Inner{ public void in(){ } } } } //一个java类中能够有多个class类,但只能有一个public class类 class A{ }
测试类:经过这个外部类来实例化内部类
package com.oop; import com.oop.demo10.Outer; //一个项目应该只存在一个main方法 public class Application { public static void main(String[] args) { Outer outer = new Outer(); //经过这个外部类来实例化内部类 Outer.Inner inner = outer.new Inner(); inner.in();//这是内部类的方法 inner.getID();//10 } }
Test类:没有名字初始化类,不用将实例保存在变量中
package com.oop.demo10; public class Test { public static void main(String[] args) { //没有名字初始化类,不用将实例保存在变量中 new Apple().eat(); new UserService(){ @Override public void hello() { } }; } } class Apple{ public void eat(){ System.out.println("1"); } } interface UserService{ void hello(); }