JavaSE
七、面向对象
1. 方法的调用补充:package com.fenfen.oop.Demo1
1.1 非静态方法下方法调用(两个不同的类)
①在Student的类中建立study的方法
package com.fenfen.oop.Demo1;
//学生类的方法
public class Student {
//方法
public void study(){
System.out.println("学生在学习");
}
}
②在Demo2类中调用Student类中的student方法
//在别的类中调用
package com.fenfen.oop.Demo1;
public class Demo2 {
public static void main(String[] args) {
//在方法非静态下:实例化这个类
//对象类型 对象名 = 对象值
Student student = new Student();
student.say();
}
}
1.2 非静态方法下的方法调用(同个类中)
public class Demo2 {
//static和类(class:Demo2)一起加载
public static void a(){
b();//会报错原因:可以理解为:存在的去调用不存在的了
}
//没有static:这个得等到类实例化(new 后)才存在
public void b(){
a();
}
}
1.3 值传递:
//值传递
public class Demo4 {
public static void main(String[] args) {
int a = 1;
change(a);
System.out.println(a);//输出仍然是a = 1
}
//无返回值
public static void change(int a){
//原因:a只是一个形式参数,a=10后没有返回值给到a,于是回到了主方法,主方法中有int a = 1,因此输出就是1了
a = 10;
}
/*
更加高端的解释:
①change方法调用完毕就出栈了,main方法还在栈中
②对于基本数据类型来说,给形参传递的是实参值的副本
而对于引用数据类型来说,传递则是地址的副本,但由于地址的副本和原来的相似,因此传递过去后的形参也指向同一个内存空间
*/
1.4 引用传递:
public class Demo5 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);//null
change(person);
System.out.println(person.name);//fenfen
}
//写个方法
public static void change(Person person){
person.name = "fenfen";//原因:引用传递:指针修改,因为引用指向原对象在内存中的区域,所以可以修改原对象的值
}
}
//定义了一个Person类,有一个属性:name
class Person{
String name;
}
2. 方法的创建与分析:com.fenfen.oop.Demo2
2.1 类和方法的创建:Student,Application
//学生类
public class Student {
//①属性:字段
String name;//未赋任何值,默认初始化为null
int age;//为赋任何值,初始化为0
//②方法
public void study(){
System.out.println(this.name+"学生在学习");//this表示当前这个类
}
}
public class Application {
public static void main(String[] args) {
//实例化:student对象就是一个Student类的具体实例
Student student = new Student();
Student xiaoming = new Student();
Student xiaohong = new Student();
//给对象赋值:
xiaoming.name = "小明";
xiaoming.age = 3;
//打印赋值后的对象属性:未赋值出来是null和0
Person person = new Person();
System.out.println(person.name);
}
}
2.2 构造器详解
2.2.1 无参构造器
public class Person {
String name;
//1、一个类即使什么都不写,也会存在构造方法(和类名相同,且无返回值),即构造器:无参构造器
//构造器的作用:实例化初始值:使用new对象,本质是在调用构造器
public Person(){
this.name = "fenfen";
}
public class Application {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);//fenfen
}
2.2.2 有参构造器
public class Person {
String name;
//2、有参构造器:一旦定义了有参构造,无参就必须显示定义(就是有了有参,无参不能删,空着就好)
public Person(){
}
public Person(String name){
this.name = name;
}
public class Application {
public static void main(String[] args) {
//实例化了一个对象:走的无参构造器
Person person = new Person();
System.out.println(person.name);
//走有参构造器
Person person1 = new Person("fenfen");
System.out.println(person1.name);
}
}
//注:快捷键alt+insert然后点击constructor,可以选择无参或有参快速生成构造器
2.3 创建对象内存分析:com.fenfen.oop.Demo3
栈的概念是弹压,就像子弹壳装弹,一粒一粒压进去,但是打出来的时候是从上面打出来的,最先压进去的最后弹出来,如果进去顺序是123,打出来顺序是321,这就是后进先出
队列的概念就是我们平时排队,按次序来,你排在第1个,那你就第一个轮到,就是先进先出,先到先来
2.3.1 对应代码
public class Pet {
public String name;
public int age;
public void shout(){
System.out.println("叫了一声");
}
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name = "馒头";
dog.age =1;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
}
}
2.3.2 对应内存顺序图:
3. 三大特性:
3.1 封装:com.fenfen.oop.Demo4
3.1.1 相关概念:
原因: |
---|
a.程序设计应”高内聚,低耦合“,即类的内部数据操作细节不允许外界干涉,以及仅暴露少量方法给外部使用 |
b.封装:应禁止直接访问一个对象中数据的实际显示,通过操作接口去访问,以便信息隐藏 |
3.1.2 封装:Student2
//封装:属性私有 get/set
public class Student2 {
//名字、姓名、学号:一般封装对于属性来说比较多,对于方法少一些
//学习、睡觉
private String name;
private int id;
private char sex;
private int age;
//提供一些可以操作的这个属性的方法:因为上面private了
//提供一些public的get、set的方法
//①get获得这个数据
public String getName() {
return this.name;
}
//②set 给这个数据设置值
public void setName(String name){
this.name = name;
}
//注:快捷键alt+insert然后点击setter and getter,可以快速生成
//③甚至可以在set里面写if判断来进行安全性检查
public void setAge(int age) {
if (age>120 || age<0) {
this.age = 3;
}else{
this.age = age;
}
}
}
public class Application {
public static void main(String[] args) {
Student2 s1 = new Student2();
//s1.name = "fenfen";私有的不可调用
String name = s1.getName();//get
s1.setName("fenfen");
System.out.println(s1.getName());//s1.getName().sout
s1.setAge(999);
System.out.println(s1.getAge());
}
}
3.1.3 封装的意义:
封装的意义:
1、提高程序的安全性,保护数据
2、隐藏代码的实现细节
3、统一接口
4、提高系统的可维护性
5、封装和重载一般一起用的比较多
3.2 继承:com.fenfen.oop.Demo5
3.2.1 子类继承父类的方法与属性
public class Person {
public int money = 10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
}
public class Student extends Person{
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.money);
}//子类继承父类,就会拥有父类的方法
3.2.2 子类继承父类私有的属性
public class Person {
private int money2 = 99999999;
//get和set方法针对private搞个封装
public int getMoney2() {
return money2;
}
public void setMoney2(int money2) {
this.money2 = money2;
}
}
public class Student extends Person{
public static void main(String[] args) {
Student student = new Student();
//针对private的封装方法的调用
student.setMoney2(99);
System.out.println(student.getMoney2());
}
}
//注: //ctrl+h可以弹出继承树
3.2.3 super详解
3.2.3.1 super在属性上的运用
- 父类
public class Person {
//protected
protected String name = "fenfen父类";
}
- 子类
public class Student extends Person{
private String name = "fenfen子类";
public void test(String name){
System.out.println(name);//main传递过来的参数
System.out.println(this.name);
System.out.println(super.name);//super去调用父类的
}
}
- Application类
public class Application {
public static void main(String[] args) {
com.fenfen.oop.Demo5.Student student1 = new com.fenfen.oop.Demo5.Student();
student1.test("fenfenmain类");
}
}
3.2.3.2super在方法上的运用
- 父类
public class Person {
public void print(){//如果是私有的方法,子类就不能直接访问了
System.out.println("Person");
}
}
- 子类
public class Student extends Person{
public void print(){
System.out.println("Student");
}
public void test1(){
print();//当前方法
this.print();//当前方法
super.print();//父类的方法
}
}
- Application类
public class Application {
public static void main(String[] args) {
com.fenfen.oop.Demo5.Student student1 = new com.fenfen.oop.Demo5.Student();
student1.test1();
}
}
3.2.3.3 super在无参构造器上的运用
- 父类
public class Person {
public Person(){
System.out.println("Person无参执行了");
}
protected String name = "fenfen父类";
}
- 子类
public class Student extends Person{
public Student() {
//隐藏代码:调用了父类的无参构造
//即有一行:super();且调用父类的构造器必须在子类的第一行
System.out.println("子类的无参执行了");
}
private String name = "fenfen子类";
}
- Application类:
public class Application {
public static void main(String[] args) {
com.fenfen.oop.Demo5.Student student1 = new com.fenfen.oop.Demo5.Student();
}
}
/*
Person无参执行了
子类的无参执行了
*/