一,继承
this:代表成员变量对象引用
super:代表父类对象引用
父类
public class Fu {
public int age = 32;
}
子类
public class Zi extends Fu {
public int age = 545;
public void show(){
int age= 31;
System.out.println(age);
//查看成员变量中的age
System.out.println(this.age);
//查看父类中的age
System.out.println(super.age);
}
}
测试类
public class Demo {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?
通过使用super关键字去显示的调用父类的带参构造方法
在父类中自己提供一个无参构造方法
推荐:自己给出无参构造方法
父类
public class Fu {
// public Fu(){
// System.out.println("fu无参构造方法被调用");
// }
public Fu(int age){
System.out.println("fu带参构造方法被调用");
}
}
子类
public class Zi extends Fu {
public Zi(){
super(20);
System.out.println("zi中无参方法被调用");
}
public Zi(int age){
super(41);
System.out.println("zi中带参方法被调用");
}
}
测试类
public class Demo {
public static void main(String[] args) {
Zi z = new Zi();
Zi z2 = new Zi(20);
}
}
练习
父类
public class People {
private String name;
private int age;
public People (){}
public People(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
子类
public class Student extends People {
public Student(){}
public Student(String name,int age){
super(name,age);
}
public void study(){
System.out.println("好好学习,天天向上");
}
}
public class Teacher extends People {
public Teacher(){}
public Teacher(String name,int age){
super(name,age);
}
public void teach(){
System.out.println("教书育人");
}
}
测试类
public class Demo {
public static void main(String[] args) {
Teacher t1 = new Teacher();
t1.setName("张三");
t1.setAge(20);
System.out.println(t1.getName() + "," +t1.getAge());
t1.teach();
Teacher t2 = new Teacher("王五",55);
System.out.println(t2.getName() + "," +t2.getAge());
t2.teach();
Student s1 = new Student();
s1.setAge(55);
s1.setName("好嘛");
System.out.println(s1.getName() + "," +s1.getAge());
s1.study();
Student s2 = new Student("强军",88);
System.out.println(s2.getName() + "," +s2.getAge());
s2.study();
}
}
二,多态
多态:同一个对象,在不同时刻表现出来的不同形态
举例:猫
我们可以说猫是猫: 猫 cat= new 猫( );
我们也可以说猫是动物: 动物 animal = new 猫();
这里通在不同的时刻表现出来了不同的形态,这就是多态
多态的前提和体现
有继承/实现关系
有方法重写
有父类引用指向子类对象
父类
public class Animal {
public void show(){
System.out.println("动物吃东西");
}
}
子类
public class Cat extends Animal {
@Override
public void show() {
System.out.println("猫吃鱼");
}
}
测试类
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
a.show();
Cat c = new Cat();
c.show();
Animal a1 = new Animal();
a1.show();
}
}
多态中成员访问特点
成员变量:编译看左边。执行看左边
成员方法:编译看左边。执行看右边
为什么成员变量和成员方法的访问不一样呢?
因为成员方法有重写,而成员变量没有
父类
public class Animal {
public int age = 43;
public void eat(){
System.out.println("动物吃东西");
}
}
子类
public class Cat extends Animal {
public int age = 10;
public int weight = 54;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame(){
System.out.println("猫捉迷藏");
}
}
测试类
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
System.out.println(a.age);
// System.out.println(a.weight);
a.eat();
// a.playGame();
}
}
多态的好处和弊端
多态的好处:提高了程序的扩展性
具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的了类型参与操作
多态的弊端:不能使用子类的特有功能
父类
public class Animal {
public void eat(){
System.out.println("动物吃东西");
}
}
子类
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗啃骨头");
}
public void lookDoor(){
System.out.println("狗看门");
}
}
操作类
public class AnimalOperator {
/*
public void useAnimal(Cat c){
c.eat();
}
public void useAnimal(Dog d){
d.eat();
}
*/
public void useAnimal(Animal a){
//Animal a = new Cat;
//Animal a = new Dog;
a.eat();
// a.lookDoor();
}
}
测试类
public class AnimalDemo {
public static void main(String[] args) {
//创建动物操作类的对象,调用方法
AnimalOperator ao = new AnimalOperator();
Cat c = new Cat();
ao.useAnimal(c);
Dog d = new Dog();
ao.useAnimal(d);
}
}
向上转型
从子到父
父类引用指向子类对象
向下转型
从父到子
父类引用转为子类对象
父类
public class Animal {
public void eat(){
System.out.println("动物吃东西");
}
}
子类
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
测试类
public class AnimalDemo {
public static void main(String[] args) {
//多态
Animal a = new Cat();//向上转型
a.eat();
// a.playGame();
//向下转型
Cat c = (Cat)a;
c.eat();
c.playGame();
}
}
三,递归
递归概述:
以编程的角度来看,递归指的是方法定义中调用方法本身的现象
public class DiGuiDemo {
public static void main(String[] args) {
//回顾不死神兔问题,求第20个月兔子的对数
// 每个月的免子对数。1,1,2,3,5,8...
int[] arr = new int[20];
arr[0] = 1;
arr[1] = 1;
for(int x = 2; x < arr.length; x++){
arr[x] = arr[x-1] + arr[x-2];
}
System.out.println(arr[19]);
System.out.println(f(20));
}
/*
递归解决问题,首先就是要定义一个方法:
定义一个方法f(n),表示第n个月的兔子对数
*/
public static int f(int n ){
if(n == 1 || n == 2){
return 1;
}else{
return f(n-1) + f(n-2);
}
}
}
练习
/*
用递归求5的阶乘,并把结果在控制台输出
思路:
1 :定义一个方法,用于递归求阶乘。参数为一个int类型的变量
2:在方法内部判断该变量的值是否是1
是:,返回1
不是:返回n*(n-1 )!
3:调用方法
4:输出结果
*/
public class DiGuiTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字:");
int num = sc.nextInt();
//调用方法
int result = jc(num);
System.out.println(num + "的阶乘是:" + result);
}
//定义一个方法,用于递归求阶乘。参数为一个int类型的变量
public static int jc(int n){
// 在方法内部判断该变量的值是否是1
if(n == 1){
//是:,返回1
return 1;
}else {
//不是:返回n*(n-1 )! jc表示阶乘
return n*jc(n-1);
}
}
}
*
需求:
需求:给定一个路径,请通过递归完成遍历该目录下的所有内容,并把所有文件的绝对路径输出在控制台
思路:
1 :根据给定的路径创建一个FiLe对象
2:定义一个方法,用于获取给定目录下的所有内容,参数为第1步创建的FiLe对象
3获取给定的FiLe目录下所有的文件或者目录的FiLe数组
4:遍历该File数组,行到每—个File对象
5:判断该File对象是否是目录
是:递归调用
不是:获取绝对踏径输出在控制台
6 :调用方法
*/
public class DiGuiDemo {
public static void main(String[] args) {
//根据给定的路径创建一个FiLe对象
File f = new File("D:\\p2\\org.eclipse.equinox.p2.core");
getAllFilePath(f);
}
//定义一个方法,用于获取给定目录下的所有内容,参数为第1步创建的FiLe对象
public static void getAllFilePath(File f) {
//获取给定的FiLe目录下所有的文件或者目录的File数组
File[] arr = f.listFiles();
//遍历该File数组,行到每—个File对象
if (arr != null) {
for (File file : arr) {
//判断该File对象是否是目录
if (file.isDirectory()) {
//是:递归调用
getAllFilePath(file);
} else {
//不是:获取绝对踏径输出在控制台
System.out.println(file.getAbsoluteFile());
}
}
}
}
}
四,封装
封装原则
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问成员变量private,提供对应的getXxox0/setXxx()方法
4.1 private关键字
是一个权限修饰符
可以修饰成员(成员变量和成员方法)
作用是保护成员不被别的类使用,被private修饰的成员只在本类中才能访问
针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰
提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰
package com.ithema_04;
/*
学生类
*/
public class Student {
//成员变量
String name;
private int age;
//提供get/set方法
public void setAge(int a){
if (a<0 || a>120){
System.out.println("你给的年龄有误");
}else{
age = a;
}
}
public int getAge(){
return age;
}
//成员方法
public void show(){
System.out.println(name + "," +age);
}
}
package com.ithema_04;
/*
学生调用类
*/
public class StudentDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
//给成员变量赋值
s.name = "小猪";
//s.setAge(-20);
s.setAge(-50);
//调用方法
s.show();
}
}
4.2 private关键字的使用
一个标准类的编写:
把成员变量用private修饰
提供对应的getXxx0/setXox(方法
package com.ithema_05;
/*
学生类
*/
public class Student {
//成员变量
private String name;
private int age;
//get/set方法
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
public void setAge(int a){
age = a;
}
public int getAge(){
return age;
}
public void show(){
System.out.println(name + "," + age);
}
}
package com.ithema_05;
/*
测试类
*/
public class StudentDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
//使用set方法给成员变量赋值
s.setName("小猪");
s.setAge(20);
s.show();
//使用get方法获取成员变量值
System.out.println(s.getName() + "---" + s.getAge());
System.out.println(s.getName() + ",,," + s.getAge());
}
}
4.3 this关键字
this修饰的变量用于指代成员变量
方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量
方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量
什么时候使用this呢?解决局部变量隐藏成员变量
this:代表所在类的对象引用
记住:方法被哪个对象调用,this就代表哪个对象
package com.ithema_06;
/*
学生类
*/
public class Student {
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void show() {
System.out.println(name +"," + age);
}
}
/*
测试类
*/
package com.ithema_06;
public class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
s.setName("小猪");
s.setAge(180);
s.show();
}
}