面向对象是搭建框架,面向过程是实现流程。
面向对象编程的本质就是,以类的方式组织代码,以对象的形式封装数据。
抽象:将类似的、同类的事物抽取出来。
三大特征:
类和对象:对象是具体的事物,类是对象的模板。例如“猫”是一个类,具体的一只猫就是一个对象,这只猫的颜色、大小、品种就是这个对象的属性。从代码运行的角度看是先有类后有对象。
修饰符
返回类型
方法名:见名知意,驼峰命名法
参数列表:参数类型,参数名。
break和return的区别:break结束switch、跳出循环;return结束方法,返回一个结果。
异常跳出
package oop;
import java.io.IOException;
public class Demo01 {
public static void main(String[] args) {
}
/*修饰符 返回值类型 方法名(参数)
{
//方法体
return 返回值;
}
*/
public String sayHello()
{
return "Hello,world!";
}
public int max(int a,int b)//a,b是形参,实参和形参要一一对应
{
return a>b?a:b;
}
//异常:数组下标越界:Arraysindexoutofbounds
public void readFile(String file) throws IOException{}//抛出异常
}
静态方法与非静态方法
package oop;
public class Demo02 {
public static void main(String[] args) {
}
//静态方法 static
//非静态方法 没有static
public static void a(){
}//静态方法、类方法和类一起加载
public void b(){
a();//静态方法在同一类下可以直接调用,也可以通过类直接调用
// Demo02.a();
}//b是非静态方法、对象方法,要类实例化之后才存在
}
package charactor;
public class Hero {
public String name;
protected float hp;
//实例方法,对象方法,非静态方法
//必须有对象才能够调用
public void die(){
hp = 0;
}
//类方法,静态方法
//通过类就可以直接调用
public static void battleWin(){
System.out.println("battle win");
}
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
//必须有一个对象才能调用
garen.die();
Hero teemo = new Hero();
teemo.name = "提莫";
//无需对象,直接通过类调用
Hero.battleWin();
}
}
形参和实参:形参就是方法中的形式上的参数,实参是调用方法时传递给方法的实际参数,形参和实参要保证类型的一致。
值传递:
在方法被调用时,实参通过形参把它的内容副本传入方法内部,此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容。
如果是对基本数据类型的数据进行操作,由于原始内容和副本都是存储实际值(拥有数据),并且是在不同的栈区,因此形参的操作,不影响原始内容。
package oop;
//值传递
public class Demo04 {
public static void main(String[] args) {
int a=1;
System.out.println("a = " + a);
Demo04.change(a);
//输出a=1;值传递传递的是真实内容的一个副本,对副本的操作不影响原内容,也就是形参怎么变化,不会影响实参对应的内容。
a=Demo04.change(a);//这里是将返回值赋值给a,a得到了新的值。
System.out.println("a = " + a);//输出a=10;
}
public static int change(int a){
a=10;
return a;
}
}
引用传递:
实际上也是值传递。对象是指向数据的,对象并不拥有数据,所以指向不变的时候,数据是可以被改变的。对引用类型的数据进行操作,分两种情况,一种是形参和实参保持指向同一个对象地址,则形参的操作,会影响实参指向的对象的内容。一种是形参被改动指向新的对象地址(如重新赋值引用),则形参的操作,不会影响实参指向的对象的内容。
package oop;
//引用传递,本质还是值传递
public class Demo05 {
static class Person{
String name;
public void changeName(Person person){
person.name="辛幼安";
}
}
public static void main(String[] args) {
Person person=new Person();
person.name="辛弃疾";
person.changeName(person);//对象方法,通过对象来调用
System.out.println(person.name);//输出辛幼安
}
}
package oop;
//引用传递,本质还是值传递
public class Demo05 {
static class Person{
String name;
public void changeName(String name){
name="辛幼安";
}
}
public static void main(String[] args) {
Person person=new Person();
person.name="辛弃疾";
person.changeName(person.name);//对象方法,通过对象来调用
System.out.println(person.name);//输出辛弃疾,因为person是对象,person.name是一个具体值
}
}
因此可见:在Java中所有的参数传递,不管基本类型还是引用类型,都是值传递,或者说是副本传递。
this关键字
package oop;
//学生类,任何一个类都只包含属性和方法
public class Student {
//属性
String name;
int age;
//方法
public void study(){
System.out.println(this.name+"在学习!");
}
public static void main(String[] args) {
//类是抽象的,需要实例化。对象就是Student类的具体实例
Student student1=new Student();
student1.name="小明";//如不赋值,则默认初始化为null
student1.age=10;//默认初始化为0;
Student student2=new Student();
student2.name="小红";
student2.age=9;
}
}
构造器的特点与作用:
String name;
int age;
//一个类即使什么也不写,也会存在一个方法,会有一个默认的空构造器;
//构造器没有返回值,名字与类名相同
//public Person(){}
//实例化初始值
//1.使用new关键字必须要有构造器。
//2.用来初始化值
public Person(){
this.name="辛弃疾";
}
//有参构造一旦被定义,有参构造就必须被显示定义
public Person(String name){
this.name=name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Person person=new Person("辛弃疾");
Person person1=new Person("陆游",55);
}
//生成构造方法的快捷键:alt+Ins(Shift)
类是一个模板,抽象;对象是一个具体的实例。
方法:定义和调用;
对应的引用:引用类型、8个基本类型。对象是通过引用来操作的。栈—>堆
属性:成员变量
默认初始化:
引用:null;
数字:0;
char:u000;
boolean:false;
赋值: 修饰符 属性名=属性值
对象的创建和使用:必须使用new关键字创造对象,通过构造器。
对象的方法、属性都是通过点(.)操作符来调用。
类:静态的属性;动态的行为——方法。
package oop;
import java.util.Arrays;
//学生类,任何一个类都只包含属性和方法
public class Student {
//姓名,学号,性别,年龄,学习();
//封装主要是对于属性,属性私有;
private String name;
private int id;
private char sex;
private int age;
//提供一些可以操作这些属性的方法。
//set 给这个数据设置值
public void setName(String name){
this.name=name;
}
//get 获得这个数据
public String getName(){
return this.name;
}
//alt+insert(Shift)自动生成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){
System.out.println("年龄不合法");
}//可以用于判断合法性
else
{
this.age = age;
}
}
public static void main(String[] args) {
Student student1=new Student();
student1.setName("小明");
student1.name=student1.getName();
System.out.println(student1.name);
}
}
pulic class Student extends Person{}
package oop;
public class Person {
//属性一般是私有的,可以通过get,set方法来接入
private int money=10_0000_0000;
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public void say(){
System.out.println("说了一句话!");
}
}
/*------------------------------------------*/
package oop;
import java.util.Arrays;
//子类继承父类,会继承父类的所有的方法
public class Student extends Person{
public static void main(String[] args) {
Student student1=new Student();
int a=student1.getMoney();
student1.say();
}
}
//在类里面使用Ctrl+H,打开继承关系的列表
所有的类都默认继承Object类
public class Person extends Object{}
//就等于
public class Person {}
VS this:
为什么需要重写?
父类的方法,子类不一定满足或者需要。
重写快捷键:alt+Ins(Shift)–>override
package oop;
//将A类作为父类
public class A {
protected void test(){
System.out.println("test=>A");
}
}
package oop;
//B作为子类
public class B extends A {
@Override
//非静态方法
protected void test() {
System.out.println("test=>B");
}
public static void main(String[] args) {
B b=new B();
b.test();
A a=new B();
a.test();//也走了子类的方法
}
}
多态是方法的多态,属性是没有多态的。
在父类和子类之间,要有继承关系,方法需要重写。
父类引用指向子类的对象。对象可以调用的方法取决于它引用类型中的方法。
static,静态方法属于类,不能被重写。
final 常量,不能被重写。
private方法是私有,不能被重写。
package oop.Demo07;
public class Person {
private void read(){
System.out.println("person reads");
}
}
/*--------------------------------------------*/
package oop.Demo07;
public class Student extends Person{
protected void read(){
System.out.println("student reads");
}
}
/*--------------------------------------------*/
package oop.Demo07;
public class Application {
public static void main(String[] args) {
//一个类的实际对象是确定的,new Student()、new Person();
// 但可以指向的引用类型的不确定的,可以指向他的任意父类
//子类能够调用自己的方法或者父类的方法
Student s1=new Student();
//父类可以指向子类,但不能调用子类独有的方法
Person s2 = new Student();//父类的引用指向子类
Object s3=new Student();//最高父类的引用指向子类
s1.read();
// s2.read();//这里就发生了重写,Persoon类中修饰符不是private,调用的是子类Student的read
//如果父类Person方法为private,则不能调用了
((Student)s2).read();//此时要调用子类中的read,则需要将s2的引用类型强制转换
}
}
package oop.Demo06;
//B作为子类
public class B extends A {
public static void main(String[] args) {
B b=new B();
A a=new B();
System.out.println(b instanceof B);//true
System.out.println(a instanceof B);//treu
System.out.println(a instanceof A);//true
}
}
instanceof用来判断对象和类之间的所属关系。
抽象类不能new,只能通过它的子类去实现,抽象类本身只提供框架。
抽象类中必须写普通的方法,但抽象方法必须写到抽象类中。
构造函数的作用是用来实例化对象,但抽象类也有构造函数:
作用是:
package oop.Demo08;
//abstract 抽象类:类 extends:单继承
public abstract class Action {
//抽象类是提供一种约束和框架,让别人去实现具体的方法
//抽象方法只有方法名,没有方法的实现,没有方法体;
public abstract void doSomething();
//抽象类中可以写普通的方法,但抽象方法必须写在抽象类中;
public void saySomething(){
}
}
package oop.Demo09;
//定义接口的关键字:interface
public interface UserService {
//常量都是public static final
int age=22;
//接口中所有定义都是抽象的 public abstract
void add(String name);
void delete(String name);
void updata(String name);
void quary(String name);
}
/*-----------------------------------*/
package oop.Demo09;
public interface TimerService {
void timer();
}
/*------------------------------------*/
package oop.Demo09;
//类 用来实现接口 implements
//实现接口中的类,就需要重写接口中的方法
//可以实现多继承
public class UserServiceImpl implements UserService,TimerService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void updata(String name) {
}
@Override
public void quary(String name) {
}
@Override
public void timer() {
}
}