获取一个数字每一位的数值 :
规律如上
***注:引用数据类型作为参数传递,传递的是地址值,当在方法中值被改变时,其存储于堆内存中的值也会改变,而基本数据类型作为参数传递时,传递的时该参数的副本,当方法弹栈时,方法中的值会随之消失,而实际的值不会改变
--引用数据类型:
*类class:包括String,StringBuffer,ArrayList,HashSet,HashMap等
*接口interface
*数组Array
2:嵌套循环
外循环:控制行数
内循环:控制列数
3.控制循环标记
package javademo;
public class demo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
a:for(int i=1;i<=9;i++){
for(int j=1;j<=i;j++){
System.out.print(j+"*"+i+"="+i*j +" ");
if(i==8){
break a;
}
}
System.out.print("\n");
}
}
}
a:xxxxx //a就是标号,只要是合法的标志符就行
4.return
--用来返回方法
5.return,break,continue的区别
-return用来结束方法
-break用来跳出循环
-continue终止本次循环,开始下次循环s
6.方法
目的:提高代码的复用性
什么是:完成特定功能的代码块
格式: 修饰符 返回值类型 方法名(参数类型 参数1,参数2,,,参数n){
方法体语句;
return 返回值;
}
参数:
-实际参数:实际参与运算的
-形式参数:方法定义上的,用于接收实际参数的
7.键盘录入数据
-导包:import java.util.scanner
-创建对象:Scanner sc = new Scanner(System.in);
-通过对象获取数据:int x = sc.nextInt();
8.方法重载
-方法名相同,参数列表不同,与返回值类型无关
-分类:1,参数个数不同
2,参数类型不同(顺序不同)
9.数组 注:数组元素的默认值为0
-概念:数组是存储同一种数据类型多个元素的集合,也可以看成一个容器
-数组既可以存储基本数据类型,也可以存储引用数据类型
-定义格式:数据类型[] 数组名 = new 数据类型[数组的长度]
-数组的初始化:为数组开辟连续的内存空间,并为每个数组元素赋值
-动态初始化:只指定长度,由系统给出初始化值
-静态初始化:给出初始化值,由系统给出长度
-初始化值:
整数类型:byte,short,int,long 的初始化值都是0
浮点类型:float,double默认初始化值都是0.0
布尔类型:默认初始化值都是false
字符类型:默认初始化值都是'\u0000'
char在内存中占用两个字节,是16个2进制位,\u0000每一个0代表的是16进制的0
-[I@6d06d69c
[:有几个就表示几维数组
I:表示数据类型
6d06d69c:表示16进制的地址
10.内存分配
-栈:存储局部变量
局部变量:定义在方法声明和方法上的变量
-堆:存储new出来的数组或对象
11.数组异常
-ArrayIndexOutBoundsException 数组索引越界异常
原因:访问了不存在索引
-NullPointerException 空指针异常
原因:数组已经不指向堆内存了,还用数组名去访问元素
12.二维数组
范例:int[][] arr = new int [3][2]
System.out.println(arr); //输出二维数组的地址
System.out.println(arr[0]); //输出二维数组中第一个一维数组的地址
System.out.println(arr[0][0]); //输出二维数组中第一个一维数组中的第一个值
13.二维数组的遍历
外循环:控制二维数组的长度,也就是一维数组的个数
内循环:控制一维数组的长度
package javademo;
import java.util.*;
public class demo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int [][] arr ={{1,2,3},{1,2,2,5},{6,7,8}};
for(int i=0;i
15.构造方法
概述:给对象的属性(数据)进行初始化
格式特点:
-方法名与类名相同(大小写也要一致)
-无返回值类型,连void都没有
-无具体的返回值return,有return语句,格式:return;
成员变量:为保证数据的安全,成员变量都私有
注:构造方法不能用对象调用,当创建对象时,系统就调用了构造方法
16.构造方法的重载
重载:方法名相同,与返回值类型无关(构造方法无返回值),只看参数列表
注:
-如果我们没有给出构造方法,系统将自动提供一个无参的构造方法
-如果我们给出构造方法,系统将不再提供构造方法,用户只能自己声明
17.创建一个对象的步骤 Student s = new Student();
-1.Student.class加载进内存
-2.声明一个Student类型引用s(主方法进栈)
-3.在堆内存创建对象
-4.给对象中属性默认初始化值
-5.属性进行显示初始化
-6.构造方法进栈,对对象中的属性赋值,构造方法弹栈
-7.将对象的地址赋值给s
18.static关键字
-随着类的加载而加载
-优先于对象而存在
-被类的所有对象共享
-共性用静态,特性用非静态
-静态方法中是没有this关键字的,静态是随着类的加载而加载的,this是随着对象的创建而存在的
19.静态变量和成员变量的区别
-所属不同:
-1.静态变量属于类,所以又叫类变量
-2.成员变量属于对象,所以又叫实例变量(对象变量)
-内存中位置不同:
-1.静态变量存储于方法区的静态区
-2.成员变量存储于堆内存
-内存中出现时间不同:
-1.静态变量随着类的加载而存在,随着类的消失而消失
-2.成员变量随着对象的创建而存在,随着对象的消失而消失
-调用不同:
-1.静态变量可以通过类名调用,也可以通过对象调用
-2.成员变量只能通过对象名调用
20.main的详细解释
-public:被jvm调用,所以权限要足够大
-static:被jvm调用,不需要创建对象,直接类名.调用即可
-void:被jvm调用,不需要又任何的返回值
-main:只有这样写才能被jvm识别,main不是关键字
-String[] args:以前是用来接收键盘录入的
21.当一个类的所有的方法都是静态方法,会私有这个类的构造方法,目的是不让其他类创建他的对象
22.代码块
-在java中,使用{}括起来的代码称为代码块
-好处:限定变量的生命周期,例如for(;;){},在{}外无法访问()中定义的值
-常见代码块的分类:
-1.构造代码块:在类中方法外出现,每创建一次对象,就执行一次构造代码块,而且是优先执行(初始化块)
-2.局部代码块:在方法中出现,限定变量生命周期,及早释放,提高内存利用率
-3.静态代码块:在类中方法外出现,加上static修饰,随着类的加载而加载,且只执行一次,一般用来加载驱 动,优先于主方法执行。
23.继承
-让类与类之间产生关系,子父类关系
-好处:提高了代码的复用性,提高了代码的维护性,是多态的前提
-弊端:提高了类的耦合性
-开发的原则:高内聚,低耦合
-耦合:类与类之间的联系
-内聚:自己完成某件事情的能力
-注意事项:
-1.子类只能继承父类所有非私有的成员(成员变量和成员方法)
-2.子类不能继承父类的构造方法,但是可以通过super关键字来访问父类的构造方法
24.this与super
-this:代表当前对象的引用,谁来调用我,我就代表谁
-super:代表当前对象父类的引用
-使用区别:
-1:调用成员变量:
a:this.成员变量,调用本类的成员变量,也可以调用父类的成员变量
b:super.成员变量,调用父类的成员变量
-2:调用构造方法:
a:this(...),调用本类的构造方法
b:this(...),调用父类的构造方法
-3:调用成员方法:
a:this.成员方法,调用本类的成员方法,也可以调用父类的成员方法
b:super.成员方法,调用父类的成员方法
-注:子类中所有的构造方法默认会访问父类中空参的构造方法
-原因:子类会继承父类中的数据,可能还会使用父类中的数据,所以子类初始化之前,一定要先完成父类数据的初始化,其实。子类构造方法第一条语句默认为super() object类最顶层的父类
-this和super的调用构造方法不能同时写,因为它们都想成为构造方法中第一条语句
25.方法的重写
-概念:子父类出现一样名字的方法
-应用:当子类需要父类的功能,而功能主体子类有自己特有内容,可以重写父类方法,这样既沿袭了父类的方法,又定义了子类特有的内容
-注意事项 :
-1.父类中私有方法不能被重写,因为父类的私有方法子类不能继承
-2.子类重写父类的方法时,访问权限不能更低,最好一致
-3.父类的静态方法,子类必须也通过静态方法进行重写
26.方法重写和方法重载:
-区别:
方法重写:子类中出现了和父类中方法声明一模一样的方法,与返回值类型有关,返回值时一致的
方法重载:本类中出现的方法名一样,但参数列表不同的方法。与返回值类型无关
-子类对象调用方法的时候:先找子类本身,再找父类
27.final关键字
-修饰特点:
-1. 修饰类,类不能被继承
-2.修饰变量,变量就变成了常量,只能赋值一次
-3.修饰方法,方法不能被重写
28.多态
-好处:
-1.提高了代码的维护性(有继承保证)
-2.提高了代码的扩展性(有多态保证)
-弊端:不能使用子类特有的属性和方法
-注:开发时很少在创建对象的时候用上转型对象,在当作参数时用最好,因为扩展性强
-概述:事物存在的多种形态
-关键字:instanceof 判断前面的引用是否是后面的数据类型
-多态的前提:
-1.要有继承关系
-2.又有方法重写
-3.要有父类引用指向子类对象
package javademo;
public class demo4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat c = new Cat();
c.eat();
Animal a = new Cat();
a.eat(); //父类引用指向子类对象
}
}
class Animal{
public void eat(){
System.out.println("吃饭");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("吃鱼");
}
}
-变量
-指向父类
- 成员方法
-编译看父类,运行看子类,若编译时父类没有指定的方法,则会出错(动态绑定)
-静态方法
-编译看父类,运行看父类,静态与类相关,算不上重写,所以还是看父类。(只有非静态的成员方法,编译看父类,运行看子类)
-向上转型和向下转型
范例:
package javademo;
public class demo4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person p = new superman(); //父类引用指向子类对象,向上转型
System.out.println(p.name);
p.谈生意(); //父类编译,运行子类
//p.fly(); //不能这样调用,因为父类中没有fly()方法
superman sm = (superman)p; //向下转型,相当于 superman sm = new superman();
sm.fly();
}
}
class Person{
String name = "john";
public void 谈生意(){
System.out.println("谈生意");
}
}
class superman extends Person{
String name = "superman";
public void 谈生意(){
System.out.println("谈几个亿的大单子");
}
public void fly(){
System.out.println("飞出去救人");
}
}
29.抽象
-概述:抽象就是看不懂的,无法用语言描述的
-特点:
-1.抽象类和抽象方法必须用abstract关键字修饰
abstract class 类名{}
public abstract void eat(){}
-2.抽象类不一定有抽象方法,有抽象方法的类一定是抽象方法或接口
-3.抽象实例化->按照多态的方式,由具体的子类实例化,也称为抽象类多态
-4.抽象类的子类:要么是抽象类,要么重写抽象类中的所有抽象方法
-注:抽象类不能实例化,也就是创建对象
-成员特点:
-1.成员变量:可以是变量,也可以是常量。abstract不能修饰成员变量
-2.构造方法:用于子类访问父类数据的初始化
-3.成员方法:可以是抽象的,也可以是非抽象的
-成员方法特性:
-1.抽象方法:强制要求子类做的事情
-2.非抽象方法:子类继承的事情,提高代码的复用性
package javademo;
public class demo4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Cat c = new Cat();
c.show();
c.eat();
c.catchmouse();
Dog d = new Dog();
d.show();
d.eat();
d.lookhome();
}
}
abstract class animal{
String name;
int age;
public abstract void eat();
public void show(){
System.out.println(name+"..."+age);
}
}
class Cat extends animal{
public Cat() {
// TODO Auto-generated constructor stub
this.name = "猫";
this.age = 10;
}
public void eat(){
System.out.println("吃鱼");
}
public void catchmouse(){
System.out.println("抓老鼠");
}
}
class Dog extends animal{
public Dog(){
this.name = "狗";
this.age = 5;
}
public void eat(){
System.out.println("吃肉");
}
public void lookhome(){
System.out.println("看家");
}
}
面试题:
1.一个抽象类中如果没有抽象方法,能不能定义为抽象类?如果可以,有什么意义?
答:可以。目的是为了不让其他类创建本类对象,交由子类完成
2.abstract关键字不能和哪些关键字共存?
答:1.abstract和static
-被abstract修饰的方法没有方法体
-被static修饰的可以用类名调用,但是(类名.抽象方法)是没有意义的
2.abstract和final
-被abstract修饰强制子类重写
-被final的修饰的方法不让子类重写,所以他俩是矛盾的
3.abstract和private
-被abstract修饰的方法是为了让子类看到并强制重写
-被private修饰是为了不让子类访问,所以互相矛盾
30.接口
-概述:对外提供规则的都是接口
-特点:
-1.接口用关键字interface表示
interface 接口名{}
-2.类实现接口用implements表示
class 类名 implements 接口名{}
-3.接口不能实例化(按照多态的方式实现实例化)
-4.接口的子类:可以是抽象类,但是意义不大;可以是具体类,但要重写接口中的所有方法(推荐)
-成员特点:
-成员变量:只能是常量,并且是静态且公共的
默认修饰符:public static final
-构造方法:接口没有构造方法
-成员方法:只能是抽象方法
默认修饰符:public abstract
-类与类的关系:只能是单继承,可以多层继承
-类与接口的关系:实现关系,可以单实现,也可以多实现,并且可以在继承一个类的同时实现多个接口
-接口与接口的关系:继承关系,可以单继承,也可以多继承
31.抽象类与接口的区别
-成员区别:
-1.抽象类:
a:成员变量:可以变量,也可以常量
b:构造方法:有
c:成员方法:可以抽象,也可以非抽象
-2.接口:
a:成员变量:只可以是常量
b:构造方法:无
c:成员方法:只可以是抽象方法
-关系区别:
-1.类与类:继承关系,单继承
-2.类与接口:实现关系,单实现,多实现
-3.接口与接口:继承关系,单继承,多继承
-设计理念区别:
-1.抽象类:被继承体体现的是"is a"的关系,抽象类中定义的是该继承体系的共性功能
-2.接口:被实现体现的是"like a"的关系,接口中定义的是该继承体系的扩展功能
32.package关键字的概述及作用
-为什么要有包?为了将字节码(.class)文件分类存放,包就是文件夹的意思
-定义包的格式:
-package 类名;
-多级包用.分开
-注意事项:
-1.package语句必须是程序的第一条可执行语句
-2.package语句在Java中只能有一个
-3.如果没有package,默认没包名
-如何运行带包的类?
-javac编译的时候带上-d即可
javac -d . HelloWorld.java
-通过java命令运行
java 包名.helloworld
33.import关键字的概述和使用
-为什么要有import?让有包的类对调用者可见,不用写全类名
-导包格式 import 包名;
-注:这种方式导入到类的名称,可以写*来导入一个包中的所有类,但是不建议,因为会影响效率
-面试题->package,import,class这三者有顺序关系嘛?
-答:有,package必须为java程序的第一行可执行代码,其次是import,最后是class
34.四种权限修饰符
35.类及其组成所使用的常见修饰符
-修饰符:
-1.权限修饰符:private,默认的,protected,public
-2.状态修饰符:static,final
-3.抽象修饰符:abstract
-类:
-1.权限修饰符:默认修饰符,public
-2.状态修饰符:final
-3.抽象修饰符:abstract
-4.最常用:public
-成员变量:
-1.权限修饰符:private,默认的,protected,public
-2.状态修饰符:static,final
-3.最常用:private
-构造方法:
-1.权限修饰符:private,默认的,protected,public
-2.最常用:public
-成员方法:
-1.权限修饰符:private,默认的,protected,public
-2.状态修饰符:static,final
-3.抽象修饰符:abstract
-4.最常用:public
-除此以外的组合:
-成员变量:public static final
-成员方法:public static public abstract public final
-36.内部类概述及其特点
-访问特点:
-内部类可以直接访问外部类的成员,包括私有成员
-外部类要访问内部类的成员,必须创建对象
-外部类名.内部类名 对象名 = 外部类对象.内部类对象
Outer.Inner oi = new Outer().new Inter();
-内部类私有化
package javademo;
public class demo6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
outer o = new outer();
o.print();
}
}
class outer{
private int num = 10;
private class inner{ //内部类被私有化
public void method(){
System.out.println(num);
}
}
//注:当内部类私有时,只能通过此种方法来调用内部类的方法
public void print(){ //因为inner类和print方法同属于outer类中,故即使inner类私有,print方法也可以访问
inner i = new inner();
i.method();
}
}
-静态内部类的访问
-成员内部类被静态修饰后的访问方式是:
外部类名.内部类名 对象名 = 外部类名.内部类对象;
-范例:
public static void main(String[] args) {
// TODO Auto-generated method stub
//外部类名.内部类名 对象名 = 外部类名.内部类对象;
outer.inner1 oi1 = new outer.inner1();
oi1.method();
}
}
class outer{
static class inner1{
public void method(){
System.out.println("method");
}
}
}
-面试题
public static void main(String[] args) {
// TODO Auto-generated method stub
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
//要求:使用已知的变量,在控制台输出30,20,10。
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num); //调用此方法内的num,就近原则
System.out.println(this.num); //this.num调用本类中的num,此时本类指inner
System.out.println(Outer.this.num);//Outer.this限定了在Outer类下访问
}
}
}
-注:内部类之所以可以访问外部类的成员,是因为它可以获取外部类的引用(外部类名.this)
37.局部内部类的访问
-范例:
public static void main(String[] args) {
// TODO Auto-generated method stub
outer o =new outer();
o.method();
}
}
//局部内部类(内部类存在于局部方法中)
class outer{
public void method(){
int num = 10;
class inner{
public void print(){
System.out.println(num);
}
}
inner i = new inner(); //创建inner对象
i.print(); //调用内部类里的print方法
}
}
注:局部内部类访问局部变量必须用final修饰?
-答:因为当调用这个方法时,局部变量如果没用final修饰,它的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没消失想调用这个局部变量,就无法使用了。如果用final修饰局部变量,当内部类加载是,final变量会进入位于方法区的常量池,即使方法弹栈,也可以调用此变量,此时该变量的生命周期和类的生命周期一致。但jdk1.8取消了这个必须事件,所以需注意。
38.匿名内部类(局部内部类的一种)
-概述:就是内部类的简化写法
-前提:存在一个类或者接口(这里的类可以是具体类也可以是抽象类)
-格式:
new 类名或接口名(){
方法重写;
}
-本质:是一个继承该类或实现该接口的子类匿名对象
-范例:
public static void main(String[] args) {
// TODO Auto-generated method stub
outer o = new outer();
o.method();
}
}
interface inter{ //创建接口inter
public abstract void print();
}
class outer{
class inner implements inter{ //创建内部类并实现接口
public void print(){
System.out.println("print");
}
}
/*new 类名或接口名(){
* 方法重写;
* }
* */
public void method(){ //匿名内部类,隐藏类名,直接调用方法
new inter(){
public void print(){
System.out.println("匿名 print");
}
}.print(); //调用内部的print方法
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
outer o = new outer();
o.method();
}
}
interface inter{ //创建接口inter
public abstract void print();
}
class outer{
class inner implements inter{ //创建内部类并实现接口
public void print(){
System.out.println("print");
}
}
/*new 类名或接口名(){
* 方法重写;
* }
* */
public void method(){ //匿名内部类,隐藏类名,直接调用方法
new inter(){
public void print(){
System.out.println("匿名 print");
}
}.print(); //调用内部的print方法
}
}
-重写多个方法并调用(一般只在重写一个方法时使用匿名内部类)
-范例:
public static void main(String[] args) {
// TODO Auto-generated method stub
outer o = new outer();
o.method();
}
}
interface inter{ //创建接口inter
public abstract void show1();
public abstract void show2();
}
//匿名内部类一般只在重写一个方法时使用
class outer{
public void method(){
inter i= new inter(){ //当需要重写调用多个方法时,可以向上转型(父类引用指向子类对象)
public void show1(){ //但一般不推荐这样使用,因为这样不能定义子类特有的方法,子类没有类名,所以无法向下转型
System.out.println("show1");
}
public void show2(){
System.out.println("show2");
}
public void show3(){ //因为编译看父类,运行看子类,且inter接口中没有show3方法,所以无法调用show3方法
System.out.println("show3");
}
};
i.show1();
i.show2();
}
}
-匿名内部类在开发中的应用(当作参数传递)
-范例:
public static void main(String[] args) {
// TODO Auto-generated method stub
outer o = new outer();
o.method(new person(){ //匿名内部类当作参数传递
public void show(){
System.out.println("show");
}
});
}
}
abstract class person{ //创建抽象类person
public abstract void show();
}
class outer{
public void method(person p){ //设置抽象方法,并设置参数
p.show();
}
/*person p = new person() { //父类引用指向子类对象
public void show() {
System.out.println("show");
}
};*/
}
-面试题
public static void main(String[] args) {
// TODO Auto-generated method stub
Outer.method().show(); //链式编程:每次调用方法后还能调用方法,证明调用方法的返回值是对象
//Inter i = Outer.method();
//i.show();
} //Outer.method()->类名.方法表明method方法是类方法,后面.show()表明前面方法的返回值是对象
}
//要求在控制台输出”HelloWorld”
interface Inter {
void show();
}
class Outer {
//补齐代码
public static Inter method(){ //返回值是Inter对象
return new Inter(){ //匿名内部类,相当于Inter i = new Inter();
public void show(){ //编译看父类(Inter接口),运行看子类
System.out.println("HelloWorld");
}
};
}
}