面向对象4.27,5.10
面向对象编程
- 初时面向对象
本质:以类的方式组织代码,以对象的组织(封装)数据
抽象
认识论角度:先有对象后有类,对象,具体事物;类,是抽象的,是对对象的抽象
代码运行角度:先有类后有对象,类是对象的模板
- 方法回顾和加深
方法的定义:
public String a(){
return"hello world!";
}
public void b(){
return;
}
public int max(int a,int b){
return a>b?a:b;
}
-
修饰符
-
返回类型
-
break和return的区别
break跳出switch,结束循环
-
方法名
-
参数列表:参数类型,参数名
-
异常抛出
方法的调用
1. 静态方法
2. 非静态方法
3. 形参和实参
4. 值传递和引用传递
5. this关键字
java //非静态方法 public static void main(String[] args){ //实例化这个类new //new Student().say(); //对象类型 对象名=对象值 Student student=new Student(); student.say(); }
java public class Student{ //非静态方法 public void say(){ System.out.println("学生说话"); } }
```java
//静态方法
public static void main(String[] args){
Student.say();
}
```
```java
//学生类
public class Student{
//静态方法
public static void say(){
System.out.println("学生说话");
}
}
```
```
```
static和类一起加载的;类实例化之后才存在
```java
public class demo01{
public static void main(String[] args){
new demo01().add();
}
public int add(int a,int b){
return a+b;
}
}//非静态方法
```
```java
//静态方法
public class demo02{
public static void main(String[] args){
int add= demo02.add(1,2);//类名.方法名
System.out.println(add);
}
public static int add(int a,int b){
return a+b;
}
}
```
```java
//值传递
public class demo03{
public static void main(String[] args){
int a=1;
System.out.println(a);
demo03.change(a);
System.out.println(a);//1
}
//返回值为空
public static void change(int a){
a=10;
}
}
```
```java
//引用传递:对象
public class demo04{
public static void main(String[] args){
Person person=new Person();
System.out.println(person.name);
demo04.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;
}
```
- 类与对象的关系
类是一种抽象数据类型,它是对某一类事物整体描述/定义,但并不能代表某一个具体事物
对象是抽象概念的具体实例
一个项目只存在一个main方法
//学生类
public class Student{
//属性:字段
String name;//null
int age;//0
//方法
public void study(){
System.out.println(this.name+"在学习");
}
}
//应用类
public class Application{
public static void main(String[] args){
//类:抽象的,实例化
//类实例化后会返回一个自己的对象
//studnet对象就是一个Student类的具体实例
Student student=new Student();
/*
Student xiaohong=new Student();
Student xiaoming=new Student();
xiaoming.name="小明";
xiaohong.name="小红";
xiaoming.age=20;
xiaohong.age=18;
System.out.println(xiaohong.name);
System.out.println(xiaoming.name);
System.out.println(xiaohong.age);
System.out.println(xiaoming.age);
*/
}
}
- 创建与初始化对象
使用new关键字创建对象
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
构造器也成为构造方法,是在进行创建对象的时候必须要调用。并且构造器有以下两个特点
-
必须和类的名字相同
-
必须没有方法类型,也不能写void
-
public class Person{
//一个类即使什么都不写,它也会存在一个方法
//显示的定义构造器
String name;
//实例化 初始值
//1.使用new关键字,必须要有构造器
public Person(){
this.name="yy";//调用上面的name
//有参情况这行删
}
//有参构造:一旦定义了有参构造,无参就必须显示定义
public Person(String name){
this.name=name;
}
}
```
java //有参 public class Application{ public static void main(String[] args){ //new 实例化一个对象 Person person=new Person("YY"); System.out.println(person.name);//YY } }
```
alt+insert默认生成一个构造器
java //无参 public class Application{ public static void main(String[] args){ //new 实例化一个对象 Person person=new Person(); System.out.println(person.name);//yy } }
构造器作用:
1.new本质在调用构造方法
2.初始化对象的值
注意点:
1.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
- 创建对象内存分析
public class Pet{
public String name;
public int age;
//shout方法
public void shout(){
System.out.println("叫了一声");
}
}
public class Application{
public static void main(String[] args){
Pet.dog=new Pet();
dog.name="旺财";
dog.age=3;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
Pet.cat=new Pet();
cat.name="咪咪";
cat.age=1;
cat.shout();
}
}
-
简单小结类与对象
-
类是一个模板:抽象,对象是一个具体的实例
-
方法:定义、调用
-
对象的引用:
对象是通过引用来操作的:栈--->堆
- 属性:字段 成员变量
默认初始化:数字--0;char--u0000;Boolean--false;引用:null;
修饰符 属性类型 属性名=属性值
- 对象的创建和使用
必须使用new关键字创造对象,构造器 Person yy=new Person();
对象的属性:yy.name
对象的方法yy.sleep()
- 类
静态的属性 属性
动态的行为 方法
- 封装
高内聚,低耦合
属性私有,get/set
public class Student{
//属性私有
private String name;//名字
private int id;//学号
private char sex;//性别
//提供一些可以操作这个属性的方法
//提供一些public 的get、set方法
//get 获得这个数据
//set 给这个数据设置值
//学习()
//睡觉()
public String getName(){
return this.name;
}
}
public void setName(String name){
this.name=name;
}
public class Application{
public static void main(String[] args){
Student s1=new Student();
s1.name//private 调用不了
s1.setName("yy");
System.out.println(s1.getName());
}
}
alt+insert自动生成get、set方法
意义:
-
提高程序安全性
-
隐藏代码的实现细节
-
统一接口
-
提高系统可维护性
-
继承
类和类之间的关系
extends
-
子类继承父类,使用关键字extends来表示
-
public class Person{
public int money=10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
}
```
public class Student extends Person{
}
```
import ~~~.Student
public class Application{
public static void main(String[] args){
Student student=new Student();
student.say();
System.out.println(student.money);
}
}
```
-
java中,所有的类,都默认直接或间接继承Objict
-
java中,只有单继承,没有多继承
-
super
-
public class Person{
protected String name="yy";
}
```
public class Student extends Person{
private String name="yyy";
public void test(String name){
System.out.println(name);//yyyy
System.out.println(this.name);//输出当前类的yyy
System.out.println(super.name);//调父类yy
}
}
```
import ~~~.Student
public class Application{
public static void main(String[] args){
Student student=new Student();
student.test("yyyy");
System.out.println(student.money);
}
}
```
public class Student extends Person{
public Person(String name){
//隐藏代码;调用了父类无参构造
super();//调用父类构造器,必须在子类构造器的第一行
//父类无参调用不了无参
System.out.println(name);
}
}
```
public class Person{
public Person(){
}
}
```
- super注意点
1. super调用父类的构造方法,必须在构造方法的第一个
2. super必须只能出现在子类的方法或构造方法中
3. super和this不能同时调用构造方法
4. vs this:
1. 代表对象不同:
2. this:本身调用者这个对象
3. super:代表父类对象的应用
4. 前提:
5. this:没有继承也可以使用
6. super:只能在继承条件才可以使用
7. 构造方法:
8. this();本类的构造
9. super();父类的构造
-
方法重写
-
//重写都是方法的重写,和属性无关
public class B{
public static void test(){
System.out.println("B>=teat()");
}
}
```
public class A extends B{
public static void test(){
System.out.println("A>=teat()");
}
```
public class Applicatopn{
public static void main(String[] args){
//方法的调用只和左边,定义的数据类型有关
A a=new A();
a.test();//A>=teat()
//父类的引用指向子类
B b=new A();
b.test();//B>=teat()
}
}
```
public class B{
public void test(){
System.out.println("B>=teat()");
}
}
```
public class A extends B{
//alt+insert---重写方法快捷键
@Override//注解
public void test(){
super.test();//默认调用
System.out.println("A>=teat()");
}
```
public class Applicatopn{
public static void main(String[] args){
//方法的调用只和左边,定义的数据类型有关
A a=new A();
a.test();//A>=teat()
//父类的引用指向子类
B b=new A();//子类重写了父类方法
b.test();//A>=teat()
}
}
```
-
静态方法和非静态方法的区别很大
-
重写:需要有继承关系,子类重写父类的方法
1. 方法名必须相同
2. 参数列表列表必须相同
3. 修饰符:范围可以扩大:public>protected>default>private
4. 抛出的异常:范围,可以被缩小,但不能被扩大
-
重写,子类方法和父类方法必须要一致,方法体不同。
-
多态
-
多态存在的条件
1. 有继承关系
2. 子类重写父类方法
3. 父类引用指向子类对象
4. java public class Person{ public void run(){ System.out.println("run"); } }
5. java public class Student extends Person{ public void run(){ System.out.println("son"); } public void eat(){ System.out.println("eat"); } }
6. java import ~~~.Student public class Application{ public static void main(String[] args){ //一个对象的实际类型是确定的 //new Student(); //new Person(); //可以指向的引用类型就不确定了:父类的引用指向子类 //Student 能调用的方法都是自己的或者继承父类的 Student s1=new Student(); //Person 父类型,可以指向子类,但不能调用子类独有的方法 Person s2=new Student(); Object s3=new Student(); //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大 s2.run();//子类重写了父类的方法,执行子类的方法 s1.run(); s1.eat(); ((Studnet)s2).eat();//强制转换 } }
7. 注意事项
1. 多态是方法的多态,属性没有多态
2. 父类和子类,有联系 类型转换异常---ClassCastException
3. 存在条件:继承关系,方法需要重写,父类引用指向子类对象 Father f1=new Son();
8. 不能重写的方法
1. static 方法,属于类,它不属于实例
2. final 常量
3. private 方法;(私有)
9. 多态是方法的多态,属性没有多态性
- instanceof(类型转换)引用类型,判断一个对象是什么类型
1. java public class Person{ public void run(){ System.out.println("run"); } }
2. ```java
public class Student extends Person{
public void go(){
}
}
```
3. ```java
public class Teacher extends Person{
}
```
4. java import ~~~.Student public class Application{ public static void main(String[] args){ //类型之间的转化:父 子 //子类转换为父类,可能丢失自己的本来的一些方法 //高 低 Person obj=new Student(); //student将这个对象转换为Student类型,我们就可以使用Student类型的方法了 /*Student obj1=(Student)obj; student.go();*/ ((Student)obj).go(); } }
5. java //System.out.println(X instanceof Y); //能不能编译通过,取决于X和Y是否存在父子关系 //X是Y的子类型
6. java import ~~~.Student public class Application{ public static void main(String[] args){ //Object>String //Object>Person>Student //Object>Person>Student Object objtct =new Student(); System.out.println(object instanceof Student);//true System.out.println(object instanceof Persom);//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 Persom);//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 Studnet(); System.out.println(student instanceof Student);//true System.out.println(student instanceof Persom);//true System.out.println(student instanceof Object);//true System.out.println(student instanceof Teacher);//编译报错 System.out.println(student instanceof String);//编译报错 } }
7. 父类引用指向子类的对象
8. 把子类转换为父类,向上转型
9. 把父类转换为子类,向下转型;强制转换,可能丢失精度/方法
10. 方便方法的调用,减少重复的代码
-
static关键字详解
-
public class Student{
private static int age;//静态变量
private double score;
public static void main(String[] args){
Student student=new Student();
student.score;//对象调用
Student.age;//类调用
}
}
```
public class Student{
private static int age;//静态变量
private double score;
public void run(){
}
public static void go(){
}
public static void main(String[] args){
new Student().run();//对象.方法
go();
//Student.go();
}
}
```
-
非静态方法可以访问静态方法;静态方法可以调用静态方法不能调用普通方法
-
public class Person{
{
System.out.println("匿名代码块");
}
//只执行一次
static{
System.out.println("静态代码块");
}
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args){
Person person1=new Person();
System.out.println(------------------);
Person person2=new Person();
}
}
/*静态代码块
匿名代码块
构造方法
------------------
匿名代码块
构造方法
*/
```
public class Test{
public static void main(String[] args){
System.out.println(Math.random());
}
}
```
//静态导入包
import static java.long.Math.random;
public class Test{
public static void main(String[] args){
System.out.println(random());
}
}
```
-
抽象类
-
abstract修饰
-
publis abstract class Action{
//约束,有人帮我们实现
//abstract,抽象方法,只有方法名字,没有方法实现
public abstract void dosomething(){
}
}
```
//抽象类的所有方法,继承了它的子类,都必须要实现它的方法
//除非,子类也是abstract
public class A extends Action{
@Override
public void doSomething(){
}
}
```
-
不能new这个抽象类,只能靠子类去实现它:约束!
-
public class Application{
public static void main(String[] args){
//new Action();不能被实例化
}
}
```
-
抽象类中可以写普通的方法
-
抽象方法必须在抽象类中
-
接口
-
声明类的关键字是class,声明接口的关键字是interface
-
public interface UserSerivce{
//接口中的所有定义都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
```
//接口都需要有实现类
//类 可以实现接口 implement 接口
//实现了接口的类,就需要重写接口的方法
public class UserServiceImp1 implements UserServicw,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 tiner(){
}
}
```
public interface TimeService{
void timer();
}
```
-
接口可以实现多继承,类只能实现单继承
-
作用
1. 约束
2. 定义一些方法,让不同的人实现
3. public abstract
4. 常量:public static final
5. 接口不能被实例化
6. implement可以实现多个接口
7. 必须要重写接口中的方法
-
内部类
-
成员内部类
1. ```java
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);
}
}
}
```
2. java public class Application{ public static void main(String[] args){ //new Outer outer=new Outer(); //通过这个外部类来实例化内部类 Outer.Inner inner=outer.new.Inner(); inner.getID(); } }
- 静态内部类
1. java public class Outer{ private int id=10; public void out(){ System.out.println("这是外部类的方法"); } public static class Inner{ public void in(){ System.out.println("这是内部类的方法"); } } }
2. java public class Application{ public static void main(String[] args){ //new Outer outer=new Outer(); //通过这个外部类来实例化内部类 Outer.Inner inner=outer.new.Inner(); inner.getID(); } }
3. 1
4. ```java
public class Outer{
}
//一个Java类中可以有多个class类,但只能有一个public class类
class A{
}
```
- 局部内部类
1. ```java
public class Outer{
//局部内部类
public void method(){
class Inner{
public void in(){
}
}
}
}
```
- 匿名内部类
1. ```java
public class Test{
public static void mian(String[] args){
//没有名字初始化类,不用将实例保存到变量中
new Apple().eat();
UserService userservice=new UserService(){
@Override
public void hello(){
}
}
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void hello();
}
```
浙公网安备 33010602011771号