1.面向对象概述
我们学习编程语言最终目的是用程序去模拟现实生活中的事物,让事物与事物之间产生关系,然后模拟现实生活中的场景。 属性:就是对事物的描述 -------成员变量 行为:就是事物能够做什么事情 -------成员方法
成员变量:在类中方法外定义的变量都叫成员变量
语句定义格式:修饰符 数据类型 变量名;
成员方法:在类中定义
定义的格式与我们在学习是规范的定义语法是一样:
修饰符 返回值类型 方法名(参数类型1 参数名1,....){ 方法体; return xxx; } 注意:现在开始将static去掉!!!!
通过类去创建对象 //语句定义格式: //类名 对象名 = new 类名(); //根据Person类创建一个人对象 Person p1=new Person();
![对象内存图](https://i-blog.csdnimg.cn/blog_migrate/4b82739519cf73ef29b91bc5f6b53cbe.png)
class Student {
//成员变量
String name;
// int age;
private int age;
public int getAge() {
return age;
}
public void setAge(int a) {
if (a > 0 & a < 100) {
age = a;
} else {
System.out.println("========================");
System.out.println("=======年龄有误!!=======");
System.out.println("========================");
}
}
//成员方法
public void study() {
System.out.println("学习");
}
public void eat() {
System.out.println("吃饭");
}
}
public class StudentDemo {
public static void main(String[] args) {
//创建一个学生对象
Student s1 = new Student();
//给成员变量进行赋值
s1.name = "reynolds";
s1.setAge(18);
System.out.println("姓名:" + s1.name + ", 年龄:" + s1.getAge());
}
}
2.成员变量与 局部变量的区别
在类中的位置不同 成员变量 类中方法外 局部变量 方法内或者方法声明上 在内存中的位置不同 成员变量 堆内存 局部变量 栈内存 生命周期不同 成员变量 随着对象的存在而存在,随着对象的消失而消失 局部变量 随着方法的调用而存在,随着方法的调用完毕而消失 初始化值不同 成员变量 有默认的初始化值 局部变量 没有默认的初始化值,必须先定义,赋值,才能使用。
匿名对象:
匿名对象:就是没有名字的对象。 是对象的一种简化表示形式
匿名对象的两种使用情况 1.对象调用方法仅仅一次的时候 2.作为实际参数传递
例:new Demo2().fun2(new Demo())
3.三大特征
3.1 封装
3.1.1封装概述
概念:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处:
隐藏实现细节,提供公共的访问方式 提高了代码的复用性 提高安全性。
封装原则:
将不需要对外提供的内容都隐藏起来。 把属性隐藏,提供公共方法对其访问。
3.1.2 private关键字
private关键字: 是一个权限修饰符。 可以修饰成员(成员变量和成员方法) 被private修饰的成员只在本类中才能访问。
private最常见的应用: 把成员变量用private修饰 提供对应的getXxx()/setXxx()方法 一个标准的案例的使用
//对于同一个文件夹下的类,类名不能重复
class Student2 {
//成员变量
private String name;
private int age;
public void setName(String s) {
name = s;
}
public String getName() {
return name;
}
public void setAge(int i) {
age = i;
}
public int getAge() {
return age;
}
//打印所有的成员变量值
public void show() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
}
public class StudentDemo2 {
public static void main(String[] args) {
//创建一个学生对象
Student2 s1 = new Student2();
// s1.name=
s1.setName("reynolds");
s1.setAge(18);
String name = s1.getName();
int age = s1.getAge();
System.out.println("姓名:" + name + ",年龄:" + age);
System.out.println("=========================================");
s1.show();
}
}
3.1.3 this关键字
this:代表所在类的对象引用 记住: 方法被哪个对象调用,this就代表那个对象
什么时候使用this呢? 局部变量隐藏成员变量
变量使用的就近原则:先在本方法中找,如果找不到再去成员变量中去找
class Student3{
//成员变量
private String name;
private int age;
public void setName(String name) { //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() {
this.fun();
System.out.println("姓名:" + this.name + ",年龄:" + this.age);
}
public void fun(){
System.out.println("今天天气不错!!");
}
private void fun2(){
System.out.println("这是被private修饰fun2方法");
}
public void fun3(){
fun2();
}
}
public class StudentDemo3 {
public static void main(String[] args) {
//创建一个学生对象
Student3 s1 = new Student3();
// s1.name=
s1.setName("reynolds");
s1.setAge(18);
String name = s1.getName();
int age = s1.getAge();
System.out.println("姓名:" + name + ",年龄:" + age);
System.out.println("=========================================");
s1.show();
// s1.fun2();
s1.fun3();
}
}
3.1.4 构造方法
作用:给对象的数据进行初始化
语句定义格式
1)构造方法的方法名与类名一致
2)没有返回值,连void都不能出现
构造方法注意事项
如果你不提供构造方法,系统会给出默认构造方法
如果你提供了构造方法,系统将不再提供,最好俩个有参无参都定义一下
构造方法也是可以重载的
Student() {
System.out.println("=============你好=============");
}
Student(String name, int age) {
// System.out.println("这是重载的方法"+s);
this.name = name;
this.age = age;
}
使用alt+insert快捷键可以快速写构造方法和get,set方法
实例:
//以面向对象的思想,编写自定义类描述图书信息。设定属性包括:书名,作者,出 版社名,价格;方法包括:信息介绍 show()
//要求:
//1)设置属性的私有访问权限,通过公有的 get,set 方法实现对属性的访问
//2)限定价格必须大于 10,如果无效进行提示
//3)限定作者,书名为只读属性
//4)设计构造方法实现对属性赋值
//5)信息介绍方法描述图书所有信息
//编写测试类,测试图书类的对象及相关方法(测试数据信息自定)
class Book{
String bname;
String author;
String press;
int price;
public Book(String bname, String author, String press, int price) {
this.bname = bname;
this.author = author;
this.press = press;
if(price>10){
this.price = price;
}else{
System.out.println("价格无效");
}
}
public void setPrice(int price) {
this.price = price;
}
public void setBname(String bname) {
this.bname = bname;
}
public String getBname() {
return bname;
}
public String getAuthor() {
return author;
}
public String getPress() {
return press;
}
public int getPrice() {
return price;
}
public void show(){
System.out.println("书名:"+bname+"\n作者:"+author+"\n出版社:"+press+"\n价格:"+price);
}
}
public class Booktest {
public static void main(String[] args) {
Book b1=new Book("鹿鼎记","金庸","人民文学出版社",55);
b1.show();
System.out.println("-------------------------------------");
Book b2=new Book(" ","古龙","人民文学出版社",55);
b2.setBname("绝代双骄");
b2.setPrice(100);
b2.show();
}
}
类的初始化过程
3.1.5 static关键字
可以修饰成员变量和成员方法
java中将所有对象共享的成员,使用一个关键字进行修饰:static(静态的)
static关键字特点
随着类的加载而加载
优先于对象存在
被类的所有对象共享 这也是我们判断是否使用静态关键字的条件
可以通过类名调用
static的使用
1、可以修饰成员变量,成员方法
2、被static修饰的成员,属于类成员(静态成员),可以使用类名.的方式直接调用,不需要创建对象
3、静态的成员方法只能访问静态的成员(包括成员变量,成员方法)
4、非静态的成员方法既可以访问静态的成员,也可以访问非静态的成员
5、static不能修饰构造方法
6、被static修饰的成员方法中不允许出现this关键字, 因为被static修饰成员是属于类本身是优先于对象而存在的,但是呢this关键字代表的是当前对象,所以两者意思上冲突了。
静态区的使用
解释main方法的每一个单词 //public是公共的意思,指最大权限,因为main方法是由JVM所调用,所以权限一定要够大 //static,静态的意思,也就意味着不需要创建对象就可以被调用起来 //void:表示没有返回值的意思,因为main方法是由JVM所调用,给了返回值其实给的是JVM,没有意义 //main:方法的名字,定死的 //String[] args:方法的参数列表,是一个一维数组,元素类型是String类型的
3.1.6 制作帮助文档
写法实例:
package com.shujia.wyh.day06;
/**
*
* 这个类是专门对数组做操作的类,封装了比如打印数组、获取最大值等等方法,后续持续更新....
* @author xiaohu
* @version 1.0
*
*/
public class ArrayTool {
private ArrayTool(){
}
/**
* 这个方法是获取int类型的一维数组中的最大值
* @param arr arr是一维数组,元素是int类型的,参数的名字叫做arr
* @return 返回值是int类型的元素,返回的是数组中的最大值
*/
public static int getMaxNumber(int[] arr) {
int maxNum = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > maxNum) {
maxNum = arr[i];
}
}
return maxNum;
}
/**
* 这个方法用作以指定的输出格式打印int类型一维数组
* 输出的格式为:[元素1,元素2,...]
* @param arr arr是一维数组,元素是int类型的,参数的名字叫做arr
*/
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
if (i == 0) {
System.out.print("[" + arr[i] + ",");
} else if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ",");
}
}
}
}
在文件夹下运行 javadoc -d 目录 -author -version ArrayTool.java
生成帮助文档
3.1.7 代码块
在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同, 可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。 局部代码块 在方法中出现;限定变量生命周期(作用域),及早释放,提高内存利用率 构造代码块 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行 静态代码块 在类中方法外出现,加了static修饰 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且值执行一次。和创建对象无关。 静态代码块(多个静态代码块之间是按照定义的顺序执行,自上而下)--->构造代码块(多个构造代码块之间是按照定义的顺序执行,自上而下)--->构造方法
public class CodeKuaiDemo {
//在类中方法外出现,并加上static修饰
static {
System.out.println("这是静态代码块2。。。。");
}
CodeKuaiDemo(){
System.out.println("这是我们自己提供的构造方法");
}
//构造代码块定义在类中方法外的,这个在创建对象的时候执行
{
int a = 10;
System.out.println("hello World2构造代码块");
}
//在类中方法外出现,并加上static修饰
static {
System.out.println("这是静态代码块3。。。。");
}
//构造代码块定义在类中方法外的,这个在创建对象的时候执行
{
int a = 10;
System.out.println("hello World3构造代码块");
}
//在类中方法外出现,并加上static修饰
static {
System.out.println("这是静态代码块1。。。。");
}
public static void main(String[] args) {
//局部代码块,在方法中出现
// {
// int a = 10;
// System.out.println("hello World");
// }
// System.out.println(a);
CodeKuaiDemo codeKuaiDemo = new CodeKuaiDemo();
System.out.println("=========================");
CodeKuaiDemo codeKuaiDemo2 = new CodeKuaiDemo();
}
}
3.2 继承
3.2.1 继承概述
把多个类中相同的部分提取到另一个类中,然后让多个类继承自这个类。
java使用extends关键实现继承的
class 子类 extends 父类{}
class Fu{
public void run(){
System.out.println("跑");
}
}
class Zi extends Fu{
}
public class ExtendsDemo {
public static void main(String[] args) {
Zi zi = new Zi();
zi.run();
}
}
继承的好处
提高了代码的复用性 多个类相同的成员可以放到同一个类中 提高了代码的维护性 如果功能的代码需要修改,修改一处即可 让类与类之间产生了关系,是多态的前提 其实这也是继承的一个弊端:类的耦合性很强 开发思想:低耦合,高内聚
继承的特点
1、java中的继承不允许一个类同时继承多个类,只能单继承 2、java中的类支持多层继承,形成继承体系
继承的注意事项
1、子类只能继承父类中非私有的成员(成员变量或者成员方法) 2、继承关系中,子类无法继承父类的构造方法,父类构造方法最重要的意义是初始化子类对象之前,必须先对父类做初始化(要想有儿子,必须先有父亲) 3、不要为了部分的功能去使用继承
class Fu2{
Fu2(){
System.out.println("父类中的构造方法");
}
}
class Zi2 extends Fu2{
Zi2(){
System.out.println("子类中的构造方法");
}
}
public class ExtendsDemo2 {
public static void main(String[] args) {
Zi2 z=new Zi2(); //创建子类对象时,必须先对父类进行初始化
}
}
输出结果:
3.2.2 super关键字
super的用法和this很像 this代表本类对应的引用。
super代表父类存储空间的标识(可以理解为父类引用)
用法(this和super均可如下使用)
访问成员变量 this.成员变量 super.成员变量
访问构造方法(子父类的构造方法问题讲) this(…) super(…)
访问成员方法(子父类的成员方法问题讲) this.成员方法() super.成员方法()
package com.bigdata.learn.day07;
class Fu3{
int a=10;
}
class Zi3 extends Fu3{
int a=555;
public void prin(int a){
System.out.println(a); //采取就近原则
System.out.println("this:"+this.a); //获取本方法中的a变量
System.out.println("super:"+super.a); //获取父方法中的a变量
}
}
public class ExtendsDemo3 {
public static void main(String[] args) {
Zi3 zi3 = new Zi3();
int a=666;
zi3.prin(a);
}
}
输出结果:
继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法
1、子类的构造方法中第一句话上面默认会有一个super(),super()的意义就是调用父类的无参构造方法 2、如果父类中没有无参构造方法怎么办? 1)解决方案1:那么我们就在子类构造方法第一句话上面使用super关键字明着调用父类的构造方法,完成父类的初始化 2)解决方案2:利用子类中其他的构造方法,间接地调用父类中的其他构造方法,完成父类的初始化
\\解决方案1
class Fu4{
Fu4(String s){
System.out.println("对父类进行初始化");
}
}
class Zi4 extends Fu4{
Zi4(){
super(" ");
}
}
public class ExtendsDemo4 {
public static void main(String[] args) {
Zi4 zi4 = new Zi4();
}
}
\\解决方法2
class Fu4{
Fu4(String s){
System.out.println("对父类进行初始化");
}
}
class Zi4 extends Fu4{
Zi4(String s){
super(s);
}
Zi4(){
this(" ");
System.out.println("子类构造方法");
}
}
public class ExtendsDemo4 {
public static void main(String[] args) {
Zi4 zi4 = new Zi4();
}
}
3.2.3 方法重写
继承中成员方法的关系
通过子类对象去访问一个方法
首先在子类中找
然后在父类中找
如果还是没有就报错。(不考虑父亲的父亲…)
方法重写概述
子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。
当子类中的方法声明(返回值类型,方法名,参数列表)与父类中的方法声明一样,这样的现象叫做方法的重写, 一般是需要在子类重写的方法上加一个注解@Override,表示该方法是重写方法
使用特点
如果方法名不同,就调用对应的方法
如果方法名相同,最终使用的是子类自己的
面试题:方法的重载与方法的重写是什么区别? 1、重载是发生在同一个类中的,而重写是发生在继承关系中。 2、重载是方法名一样,方法参数列表不一样就叫重载,和返回值类型无关 3、重写要求方法返回值类型,方法名,参数列表都要与父类中的一致,只有权限修饰符和方法体的实现不一样
class Fu5{
public void test(){
System.out.println("这是父类");
}
}
class Zi5 extends Fu5{
@Override
public void test(){
System.out.println("这是子类");
}
}
public class ExtendsDemo5 {
public static void main(String[] args) {
Zi5 zi5 = new Zi5();
zi5.test();
}
}
继承中重写的注意事项: 1、父类中私有方法不能被重写,私有的成员无法被子类继承,所以就更不要谈重写 2、子类重写父类方法时,访问权限不能更低 public private,父类什么权限修饰符号,子类重写时同步 3、父类中的静态方法无法被子类进行重写 如果父类不想让子类重写非静态的方法,只想让子类使用 java提供了一个关键字给我们使用:final (最终的,不可改变的)
3.2.4 final参数
final关键字的使用 1、final可以修饰类,成员变量,成员方法 2、被final所修饰的类,类不能被继承 3、被final所修饰的成员变量,变量变成常量,值无法被改变 常量: 1)字面值常量 2)自定义常量:final所修饰的变量 在引用数据类型之前加上final关键字,指的是引用数据类型变量的地址值不能被改变 4、被final所修饰的成员方法,不能被重写
final修饰变量的初始化时机 在对象构造完毕前即可
class Demo2{
final int a;
//构造代码块,可以在构造方法之前执行
{
a = 20;
}
Demo2(){
//..
}
public void fun1(){
System.out.println(a);
}
}
public class FinalDemo2 {
public static void main(String[] args) {
Demo2 demo2 = new Demo2();
demo2.fun1();
}
}
3.3 多态
3.3.1 多态概述
某一个事物,在不同时刻表现出来的不同状态。
举例:
猫可以是猫的类型。猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。
动物 d = new 猫();
要想实现多态,必须满足三个条件: 1、必须要有继承关系 2、要有方法的重写,如果不重写语法上没问题,但是从意思上不合适 3、在创建对象的时候,要有父类的引用指向子类对象
class Animal{
public void eat(){
System.out.println("吃");
}
}
class Cat extends Animal{
@Override
public void eat(){
System.out.println("🐱eat🐟");
}
}
public class Duotaidemo {
public static void main(String[] args) {
Animal a1=new Cat();
a1.eat();
}
}
多态案例及成员访问特点
成员变量 编译看左边,运行看左边 成员方法 编译看左边,运行看右边 静态方法 编译看左边,运行看左边
package com.bigdata.learn.day07;
class Futest{
int a=1;
public void fu(){
System.out.println("这是父中的成员方法");
}
public static void fun(){
System.out.println("这是父中的fun方法");
}
}
class Zitest extends Futest{
int a=999999;
public void fu(){
System.out.println("这是子中的成员方法");
}
public static void fun(){
System.out.println("这是子中的fun方法");
}
}
public class Duotaidemo2 {
public static void main(String[] args) {
Futest fu=new Zitest();
System.out.println(fu.a);
fu.fu();
fu.fun();
}
}
多态的好处与弊端
多态的好处 提高了程序的维护性(由继承保证) 提高了程序的扩展性(由多态保证)
多态的弊端 不能访问子类特有功能
多态的转型
向下转型
class Animal3{
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡觉");
}
}
class Dogs extends Animal3{
@Override
public void eat(){
System.out.println("🐕吃🥩");
}
@Override
public void sleep(){
System.out.println("🐕趴着睡觉");
}
}
class Cats extends Animal3{
@Override
public void eat(){
System.out.println("🐱吃🐟");
}
@Override
public void sleep(){
System.out.println("🐱蜷着睡觉");
}
}
public class Duotaidemo3 {
public static void main(String[] args) {
Animal3 animal3= new Dogs();
animal3.sleep();
Dogs d1=(Dogs) animal3;
d1.eat();
}
}
3.4 抽象类
3.4.1 抽象类概述
java提供了一个机制给我们使用,如果将来要定义的类在现实生活中的意思是表达一个抽象的概念,在程序中写的时候应该将这个类定义成抽象类 也就意味着这个类将来没法创建对象(实例化) java针对于这个机制提供了一个关键字:abstract
abstract class Animal{
public abstract void eat();
}
class Cats extends Animal{ //具体的类继承自抽象类,必须重写抽象类中的所有抽象方法
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
abstract class Demo extends Animal{ //抽象类继承抽象类
}
public class AbstractDemo1 {
public static void main(String[] args) {
Cats cats = new Cats();
cats.eat();
}
}
3.4.2 注意事项
1、一个类加上了abstract关键字就变成了抽象类,抽象类不能被实例化(不能创建对象) 2、抽象类中可以存在非抽象的方法,也可以存在抽象的方法,但是抽象的方法没有方法体 3、如果一个类中存在抽象方法,这个类必须是抽象类 4、如果一个具体的类继承自抽象类,必须重写抽象类中的所有抽象方法 5、抽象类也可以继承抽象类,可以不去重写父抽象类中的抽象方法
抽象类中成员的特点: 成员变量:可以是变量也可以是常量 构造方法:可以存在构造方法,写构造方法的意义是为了今后初始化子类之前先初始化本类 成员方法:可以存在抽象方法也可以存在含有具体实现的方法
package com.bigdata.learn.day08;
import com.sun.jmx.snmp.SnmpUnknownAccContrModelException;
abstract class Teacher{
private String name;
private int age;
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public abstract void teach();
}
class MathTeacher extends Teacher{
@Override
public void teach(){
System.out.println("数学老师教数学");
}
}
class EnglishTeacher extends Teacher{
public EnglishTeacher() {
}
public EnglishTeacher(String name, int age) {
super(name, age);
}
public void teach(){
System.out.println(getName()+"教英语");
}
}
public class AbstractDemo2 {
public static void main(String[] args) {
Teacher t1=new MathTeacher();
t1.teach(); //由于父类是抽象类,所以这种多态又有一个新的叫法:抽象多态
System.out.println("-------------------------------------------");
Teacher t2=new EnglishTeacher("smith",22);
t2.teach();
}
}
1、一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
可以。 有意义,表示现实生活中一个抽象概念的汇总,尽管类中没有其他内容,但是从逻辑上是有意义的。
2、abstract不能和哪些关键字共存 private 冲突 final 冲突 static 冲突,静态的没法重写
//因为抽象方法本身的意义就是为了今后具体的类继承抽象类去重写的 //加上了private关键字之后,子类没法重写,所以冲突
3.5 接口
3.5.1 接口概述
接口:就是某一个事物本身的功能有限,想要进行扩展功能的时候可以使用接口。当然今后接口的具体使用,是由后面具体的类实现 例 某些狗的特有功能:骑自行车,但是呢又不能直接定义在狗的类中,如果直接定义在类中,就意味着所有的狗都会骑自行车 所以java提供了一个机制给我们使用,当我们需要写扩展功能的时候,就可以定义一个接口 这里就可以将骑自行车定义成一个接口 将来哪些狗需要骑自行车,只需要实现这个接口即可
3.5.2 注意事项
注意事项: 1、接口中定义的所有方法只能是抽象方法,并且系统会默认在每一个方法前加上public abstract 2、一个类要想实现接口,使用implements关键字进行实现 3、接口中只能存在常量,默认在变量的前面加上public static final 4、抽象类可以实现接口,但是可以不去实现抽象方法,也可以实现 5、一个具体的类实现接口,必须要实现接口中所有抽象方法 6、一个类可以继承一个类的同时实现多个接口,也可以直接实现多个接口 7、接口没有构造方法,它不能创建对象(不能实例化)
//定义接口的语句格式 interface 接口名 //注意:接口名的命名方式与类名的命名方式是一样 //就将接口看作是一个特殊的类,因为接口编译的时候也会被编译成一个class文件
interface Ability{
void bike();
void skip();
}
abstract class Animal2{
abstract void eat();
}
class SpecialDog extends Animal2 implements Ability{
public void eat(){
System.out.println("狗吃肉");
}
@Override
public void bike() {
System.out.println("狗狗骑自行车");
}
@Override
public void skip() {
System.out.println("狗狗跳高");
}
}
public class InterFaceDemo1 {
public static void main(String[] args) {
SpecialDog d1=new SpecialDog();
d1.eat();
d1.bike();
d1.skip();
}
}
类和类,类和抽象类,类和接口,接口和接口之间 1、具体的类和具体的类之间只能是继承关系,只能进行单继承,不能多继承,但是可以多重继承,形成继承体系 2、类和抽象类之间也只能是继承关系,也只能进行单继承,不能多继承,但是呢如果是一个具体的类继承了抽象类,就必须实现抽象类中所有抽象方法 3、类和接口之间是一个实现关系,一个类可以实现多个接口 4、接口和接口之间是继承关系,并且允许多继承
3.5.3 形式参数与返回值类型
形式参数 基本类型: 基本数据类型当作方法的参数的时候,传入的是具体的数值 引用类型: 具体的类:今后当你看到一个类作为方法形式参数类型的时候,说明要传入该类的对象 接口:今后当你看到一个接口作为方法形式参数类型的时候,说明要传入的是实现该接口的子类对象 抽象类:今后当你看到一个抽象类作为方法形式参数类型的时候,说明要传入的是继承该抽象类的具体类的子类对象 数组:回顾前面的知识
类做引用类型
// 类做引用类型
class Student{
public void study(){
System.out.println("学习");
}
}
class StudentDemo{
public void show(Student student){
student.study();
}
}
public class CanshuDemo1 {
public static void main(String[] args) {
StudentDemo student = new StudentDemo();
student.show(new Student());
}
}
接口做引用类型
package com.bigdata.learn.day08;
interface Iner{
void fun();
}
class Inernext implements Iner{
@Override
public void fun() {
System.out.println("今天是周四");
}
}
class CanshuTest1{
public void show(Iner i){
i.fun();
}
}
public class CanshuDemo2 {
public static void main(String[] args) {
CanshuTest1 canshuTest1 = new CanshuTest1();
canshuTest1.show(new Inernext());
}
}
抽象类做引用类型
abstract class Abstract{
abstract void fun();
}
class AbstractNext extends Abstract{
@Override
public void fun() {
System.out.println("肯德基疯狂星期四");
}
}
class CanshuTest2{
public void show(Abstract i){
i.fun();
}
}
public class CanshuDemo3 {
public static void main(String[] args) {
CanshuTest2 canshuTest2 = new CanshuTest2();
canshuTest2.show(new AbstractNext());
}
}
返回值类型 基本类型:基本数据类型当作方法的返回值的,返回的是对应类的数值 引用类型: 具体的类:今后当你看到一个类作为方法的返回值类型的时候,需要返回的是该类或者是该类的子类对象 接口:今后当你看到一个接口作为方法的返回值类型的时候,需要返回的是实现该接口的子类对象 抽象类:今后当你看到一个抽象类作为方法的返回值类型的时候,需要返回的是继承该抽象类的具体子类对象 数组:回顾前面的数组知识
类做返回值
class Teacher2{
public void fun1(){
System.out.println("好好学习,天天向上");
}
}
class Teacher2Demo{
//今后当你看到一个类作为方法的返回值类型的时候,需要返回的是该类或者是该类的子类对象
public Teacher2 show1(){
return new Teacher2();
}
}
public class FanhuiZhiDemo1 {
public static void main(String[] args) {
Teacher2Demo teacher2Demo = new Teacher2Demo();
Teacher2 teacher2 = teacher2Demo.show1();
teacher2.fun1();
}
}
接口做返回值
interface Return1{
void fun();
}
class Returnnext1 implements Return1{
@Override
public void fun() {
System.out.println("xilu");
}
}
class ReturnTest1{
public Return1 show(){
return new Returnnext1();
}
}
public class ReturnDemo1 {
public static void main(String[] args) {
ReturnTest1 returnTest1 = new ReturnTest1();
Return1 r1=returnTest1.show();
r1.fun();
}
}
抽象类做返回值
略。
4.包
包的概述
其实就是文件夹
作用:对类进行分类管理
4.1 导包
导包概述 不同包下的类之间的访问,我们发现,每次使用不同包下的类的时候,都需要加包的全路径。比较麻烦。这个时候,java就提供了导包的功能。
导包格式
import 包名;
注意: 这种方式导入是到类的名称。
虽然可以最后写*,但是不建议。
4.2 权限修饰符
5 内部类
5.1内部类概述
把类定义在其他类的内部,这个类就被称为内部类。
举例:在类A中定义了一个类B,类B就是内部类。
内部类的访问特点:
内部类可以直接访问外部类的成员,包括私有。 外部类要访问内部类的成员,必须创建对象。
根据其定义的位置不同分为两种内部类:
1、成员内部类 将类定义在类中方法外 2、局部内部类 将类定义在成员方法中
5.2 成员内部类
创建对象的语句定义格式:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称(); 成员内部类可以访问外部类中的所有成员。 外部类中的成员方法中要想使用内部类中的成员,就需要创建内部类的对象
package com.bigdata.learn.day08;
class Outer{
int a=100;
private int b=99;
static int c=88;
final int d=66;
private void show1() {
System.out.println("你好,世界");
}
class Inner{
public void fun(){
int a =200;
System.out.println(this.a); //打印200
System.out.println(Outer.this.a); //打印100
System.out.println(b);
System.out.println(c);
System.out.println(d);
show1();
}
}
//外部类中的成员方法中要想使用内部类中的成员,就需要创建内部类的对象
public void show2() {
//fun1()?
Inner inner = new Inner();
inner.fun();
}
}
public class InnerDemo1 {
public static void main(String[] args) {
Outer.Inner oi=new Outer().new Inner();
oi.fun();
System.out.println("--------------------");
Outer o=new Outer();
o.show2();
}
}
5.3 局部内部类
局部内部类:将类定义在成员方法中的类
class Outer3{
int a = 11;
public void fun1(){
int a = 22;
//定义局部内部类
class Inner{
public void show1(){
// a =44; //在jdk1.8之后,局部内部类中使用的成员方法中的变量在编译的时候默认会加上final关键字
System.out.println(a);
}
}
Inner inner = new Inner();
inner.show1();
}
}
public class InnerDemo2 {
public static void main(String[] args) {
Outer3 outer3 = new Outer3();
outer3.fun1();
}
}