Java基础---面向对象
面向对象
面向对象编程的本质:以类的方式组织代码,以对象的组织(封装)数据
四大特征:封装、继承、多态、抽象(具有相同特征和行为的对象抽象成类)
方法的深入
-
方法的定义
-
修饰符
-
返回类型
-
break和return的区别
break用于switch或循环中跳出整个循环体
return表示方法结束,返回一个结果,必须与返回值类型相同;
-
方法名
-
参数列表(参数类型,参数名)
-
异常抛出 ???(以后讲)
-
-
方法的调用
- 静态方法--可以直接通过类名.方法名调用
--两个静态方法可互相调用;两个非静态方法也可以互相调用
-
非静态方法--不可直接调用,
---需要实例化(new一个对象),对象类型 对象名 = 对象值(new 对象类型)通过对象名.方法名来调用
public class student { //新建一个学生类 //非静态方法 public void say(){ System.out.println("学生说话了"); } }student zxy = new student(); //实例化 zxy.say(); //对象名.方法
-
形参和实参
-
值传递和引用传递
-
this关键字
对象的创建和分析
类和对象的关系
--类是一种抽象的数据类型,对一类事物整体的描述,不能代表某一具体事务
--对象是抽象概念的具体实例
--创建对象:new关键字--本质是调用构造器
使用new时,除了分配空间外,还会给对象默认初始化以及对类中构造方法的调用;
student zxy = new student(); //调用了构造器
public student(){ } //默认无参构造器
student wzh = new student(wangzihe); //调用构造器,有参构造
public student(String name){
this.name = name; //this.name指的是当前类中定义的name;第二个name是参数传进来的
}
//如果定义了有参构造,那么无参构造必须显示写出来
--构造方法(构造器):与类名相同;没有返回值类型,也不能写void;完成数据初始化操作;
--内存分析:对象通过引用来操作:栈---->堆

封装
- 数据的隐藏,应禁止直接访问一个对象的数据的实际表示,通过操作接口来访问
- 属性私有(private)---get/set
- 提供一些操作这些属性的方法:get(获取这个数据) set(给数据赋值)
继承
-
本质:对某一批类的抽象,是类和类之间的关系,子类和父类之间
-
关键字:extends(扩展)---子类是父类的扩展
-
Java中类只有单继承,没有多继承;----一个儿子只能有一个爸爸,一个爸爸有多个儿子
-
私有的东西无法继承
-
在Java中,所有类都默认直接或间接继承Object类
-
在执行时,子类会默认调用父类的无参构造;
-
被final修饰的类不能被继承;--final之后断子绝孙。。。
-
public class person //父类 public class student extends person //子类/派生类--学生 is 人 public class teacher extends person //子类/派生类--老师 is 人super
//主函数所在--测试类 public class test { public static void main(String[] args) { student zxy = new student(); zxy.test("hhhzxy"); }}父类 public class person { protected String name = "张二白"; }子类 public class student extends person { private String name = "zhangxiaoyang"; public void test(String name){ System.out.println(name); //输出的是(hhhzxy)主函数中传的参数 System.out.println(this.name); //输出的是(zhangxiaoyang)当前类中的name值 System.out.println(super.name);//输出的是(张二白)父类的name值 } }注意点:
1)super调用父类的构造方法,必须在构造方法的第一个
2)super必须只能出现在子类的方法中或构造方法中
3)super和this不能同时调用构造方法
与this的区别:
1)代表对象不同:
this:本身调用这个对象
super:代表父类对象的应用
2)前提:
this:没有继承也可以用
super:只能在继承条件下可用
3)构造方法
this():本类的构造
super():父类的构造
方法重写
需要有继承关系,子类重写父类的方法;子类和父类的方法必须一致,只是内容不同(方法体不同)
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大 public>protected>default>private
- 抛出的异常:范围可以被缩小,但不能扩大--(父亲欠了50万,你还了10万,还剩40万,你不能再欠了。。。)
-为什么要重写???---父类的功能,子类不一定需要或不一定满足;子类重写了父类的方法,执行时执行子类的
-什么方法不能重写:
1)static方法,属于类,不属于实例
2)被final(常量)修饰的方法
3)private方法
多态
什么是多态---同一个方法根据发送对象的不同而采用多种不同的行为方式
一个对象的实际类型是确定的---new student(); new person();
但可以指向对象的引用类型就不确定了,父类的引用指向子类
student s1 = new student(); //s1能调用的方法是自己的或继承父类的
person s2 = new student(); //person可以指向子类,但不能调用子类独有的方法
Object s3 = new student();
//对象能执行哪些方法,主要看对象左边的类型
s1.run();
s2.run(); //子类重写了父类的方法,执行子类的方法
s2.eat(); //s2是person类型,无法调用student类里独有的方法
((student)s2).eat(); //把s2强制转化成student类型,可以调用student里独有的方法
注意事项:
-
多态是方法的多态
-
父类和子类,有联系,类型转换可能发生异常-- ClassCastException!
-
存在条件:继承关系,方法需要重写,父类引用指向子类对象-father f1 = new son()
instanceof (类型转换)
Object >person >teacher Object >person >student System.out.println(X instanceof Y);//能不能编译通过,看X与Y是否有父子关系 System.out.println(Object instanceof student); //true System.out.println(student instanceof Object); //true System.out.println(student instanceof teacher); //false子类转成父类,向上转型,自动;--可能丢失自己本来的一些方法
父类转成子类,向下转型,强制转换;
类型转换方便方法的调用,减少重复代码
static详解
-
静态属性
private static int age; //静态属性 private double score; //非静态 public static void main(String[] args) { student s1 = new student(); System.out.println(student.age); //静态属性可直接用类名调用 System.out.println(student.score); //非静态不能用类名直接调用 System.out.println(s1.age); System.out.println(s1.score); -
静态方法
public void run() { go(); } //静态方法和类一起加载,非静态方法里可以调用静态方法 public static void go() { } student.run(); //报错--非静态方法不能用类.方法名调用 s1.run(); student.go(); //静态方法可直接用类调用!!!是类的加载机制的问题,非静态都还没加载进来,自然不能直接用类调用,但静态和类一起加载,故可以调用
3.静态代码块--最先执行(先于匿名代码块和构造方法),只执行一次
4.匿名代码块和对象同时产生,在构造方法之前,可以赋一些初始值
5.静态导入包-
import static java.lang.Math.random; //把Java.lang包中的Math的random()方法导入 System.out.println(Math.random());//不导入的写法 System.out.println(random()); //可以直接调用Math中的random()方法
-
抽象类和接口
抽象类(abstract class)
-
对于抽象类的所有方法,继承了抽象类的子类,都必须要实现他的方法,除非子类也是抽象类,那就由下一代来实现。。。
-
不能new这个抽象类,即不能创建实例;只能靠子类去实现它;
-
抽象类里可以写普通方法,但抽象方法必须写在抽象类里;
-
抽象类不能new,那存在构造器吗? ----存在,编译器添加默认的无参构造函数,只是不能直接创建抽象类的实例对象
-
抽象类存在的意义?
-
//抽象类 public abstract class Action { public abstract void dosomething(); //抽象方法--没有方法体,即具体的实现 }
接口(interface)
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法)都有!
-
接口:只有规范!自己无法写方法~专业的约束!约束和实现分离:面向接口编程
-
接口就是规范,定义一组规则---定义一些方法,让不同的人实现;
-
接口不能被实例化~,接口没有构造方法(他连类都不是。。。)
-
接口的本质是契约,像法律一样,制定好后大家遵守
-
其实设计模式所研究的实际上就是如何合理的去抽象,所以设计模式都只针对具备抽象能力的语言(c++,java,c#等)
-
//通过interface定义一个接口,只声明方法,不实现(类型 方法名) public interface timeService { void timer(); } public interface UserService{ void add(String nam); void delete(String nam); void update(String nam); void query(String nam); } //类 通过关键字implements实现接口,实现了接口的类必须重写接口中的方法(可以通过idea自动生成) public class UserServiceImpl implements UserService{ } //多继承---利用接口来实现 public class UserServiceImpl implements UserService,timeService{}
内部类
-
成员内部类
public class Outer { private int id = 10; public void out(){ System.out.println("这是外部类的方法");} class Inner{ public void in(){ System.out.println("这是内部类的方法"); } //内部类可以获得外部类的私有属性 public void getId(){ System.out.println(id); } } }//在测试类中 public class test { public static void main(String[] args) { Outer outer = new Outer(); //外部类new一个对象 Outer.Inner inner = outer.new Inner(); //通过外部类来实例化内部类。。。 inner.in(); inner.getId(); } }
-
静态内部类
public static class Inner{ public void in(){ System.out.println("这是内部类的方法"); } //内部类可以获得外部类的私有属性 public void getId(){ System.out.println(id); //若类变成静态内部类,就无法获得私有属性了。。。还是类的加载机制 } } -
局部内部类
public class Outer { //局部内部类---在一个方法里面定义的类 public void method(){ class Inner{ } } -
匿名内部类
class Apple { public void eat() { System.out.println("1"); } }public class test { public static void main(String[] args) { new Apple().eat(); //没有名字初始化类,不用把实例存在变量里 //正常情况下:Apple apple = new Apple(); apple.eat(); }
- 一个java类中可以有多个class类,但是只能有一个public class类
实战--人机猜拳游戏
项目开发步骤:
- 场景描述
- 四个找--找类、(若两个类很大量相同的属性和方法,可进一步抽象成父类)找属性、找方法、找关系
- 绘制类图、编写代码。
- 两个类--玩家(人、机器)、裁判
- 属性:玩家--名字、分数; 裁判:无
- 方法:玩家--说名字、出拳 裁判:说规则、问名字、开始比赛、结束比赛宣布结果
总结:
- 玩家类是父类、抽象类--属性私有、定义抽象方法、通过get、set来对操作具体的属性值。
- 人和机器分别作为两个子类,要重写父类(抽象类)的方法。
- 定义裁判类,根据场景描述(效果图)来写裁判的方法。
- 测试。
注意:一般在创建类的时候顺序:私有属性->无参构造->有参构造->get/set方法->重写 (可以重写toString来方便测试)

浙公网安备 33010602011771号