知识点积累
- 1、关于抽象类和接口:
-
-
类不可以多继承而接口可以;
-
-
-
抽象类和接口都不能被实例化,即不能通过new来实例化抽象类;
-
-
-
抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用;
-
-
-
抽象类只能用来继承;
-
-
-
抽象方法必须被子类实现。
-
-
-
接口中只有:常量、抽象方法
-
-
-
接口可以继承接口(通过extends),可以多继承
-
- 2、二维数组:
-
-
二维数组的定义中,第一个括号必须有数值,不能为空,但可为0;
-
- 3、关于抽象类:
-
-
一个子类只能继承一个抽象类,但可以实现多个接口;
-
-
-
抽象类可以有构造方法,接口没有构造方法;
-
-
-
抽象类可以有普通成员变量,接口不能有普通成员变量;
-
-
-
抽象类和接口都可以有静态成员变量,抽象类中的静态成员变量访问权限任意,接口只能是public static final(默认);
-
-
-
抽象类可以没有抽象方法,抽象类可以有普通方法, 接口中都是抽象方法;
-
-
-
抽象类可以有静态方法,接口不能有静态方法;
-
- 4、关于final的重要知识点:
-
-
final关键字可以用于成员变量、本地变量、方法以及类;
-
-
-
final修饰的成员变量必须在声明时被初始化,或者在构造器中初始化,否则就会报编译错误;
-
-
-
不能够对final变量再次赋值;
-
-
-
本地变量必须在声明时赋值;
-
-
-
在匿名类中所有变量都必须是final变量;
-
-
-
final修饰的方法不能被重写;
-
-
-
final修饰的类不能被继承;
-
-
-
没有在声明时初始化的final变量称为空白final变量(blank final variable),他们必须在构造器中初始化,或者调用this进行初始化,不然编译器会报错
-
- 5、操作数据类型为byte、short、int 、char时,两个数都会被转换成int类型,并且结果也是int类型(在进行+,-,*,/,%运算操作时)
- 6、方法入参:
-
-
方法入参是基本类型时,传递的是值,方法内对传递值进行修改时不会影响调用是的变量;
-
-
-
方法入参是引用类型时,传递的是引用地址,方法内对传递值进行修改时会影响调用时的变量;
-
package com.javasm.work3;
import java.util.Arrays;
public class TestMethod {
public static void main(String[] args) {
TestMethod method=new TestMethod();
int b = 1;
b = method.test1(b);
System.out.println(b);
int[] arr = {1,2,3};
method.test2(arr);
System.out.println(arr[0]);
System.out.println(arr);
Arrays.sort(arr);
}
/**
* 方法入参是基本数据类型时,传递的是值
* 方法内对传递的值进行修改时不会影响调用时的变量
* @param a
*/
public int test1(int a){
a=2;
return a;
}
/**
* 方法入参是引用数据类型时,传递的是内存地址引用
* 方法内对传递的引用进行修改时会影响调用时的变量
* @param arr1
*/
public void test2(int[] arr1){
System.out.println(arr1);
arr1[0] = 4;
}
}
- 7、父类的普通方法可以被继承和重写,不多作解释,如果子类继承父类,而且子类没有重写父类的方法,但是子类会有从父类继承过来的方法。
-
- 静态的方法可以被继承,但是不能重写。 如果父类中有一个静态的方法,子类也有一个与其方法名,参数类型,参数个数都一样的方法,并且也有static关键字修饰,那么该子类的方法会把原来继承过来的父类的方法隐藏,而不是重写。通俗的讲就是父类的方法和子类的方法是两个没有关系的方法,具体调用哪一个方法是看是哪个对象的引用;这种父子类方法也不在存在多态的性质。《Java编程思想》中这样提到“只有普通的方法调用可以是多态的”。下面代码为例:
public class StaticTest
{
public static void main(String[] args)
{
M m = new N();
m.output();
}
}
class M
{
public static void output()
{
System.out.println("M");
}
}
class N extends M
{
public static void output()
{
System.out.println("N");
}
}
上面执行的结果是“M”,也就是是M类型的引用调用的,如果修改main方法中的代码:
N n = new N();
n.output();
那么执行的结果是“N”,也就是N类型的引用调用的。
- 8、 为什么静态成员、静态方法中不能用this和super关键字?
-
- 1、在静态方法中是不能使用this预定义对象引用的,即使其后边所操作的也是静态成员也不行.
因为this代表的是调用这个函数的对象的引用,而静态方法是属于类的,不属于对象,静态方法成功加载后,对象还不一定存在
- 1、在静态方法中是不能使用this预定义对象引用的,即使其后边所操作的也是静态成员也不行.
-
- 2、 在问题之前先讲super的用法:
-
-
- 1.super的用法跟this类似,this代表对本类对象的引用,指向本类已经创建的对象;而super代表对父类对象的引用,指向父类对象;
-
-
-
- 2.静态优先于对象存在;
-
-
-
- 3.由上面的1.和2.知:
因为静态优先于对象存在,所以方法被静态修饰之后方法先存在,而方法里面要用到super指向的父类对象,但是所需的父类引用对象晚于该方法出现,也就是super所指向的对象没有,当然就会出错。综上,静态方法中不可以出现super关键字。
- 3.由上面的1.和2.知:
-
-
- 3、首先你要明白对象和类的区别。
-
-
- this和super是属于对象范畴的东西,而静态方法是属于类范畴的东西
-
-
-
- 所有的成员方法都有一个默认的的参数this(即使是无参的方法),只要是成员方法,编译器就会给你加上this这个参数如:
-
-
-
-
Class A中void method1(){}实际上是这样的--------> void method1(A this)
-
-
-
-
-
void method2(int x){}实际上是这样的--------> void method2(A this, intx)
而静态方法与对象无关,根本不能把对象的引用传到方法中,所以不能用this
-
-
-
- 4、在一个类中定义一个方法为static,则为静态方法,那就是说,无需本类的对象即可调用此方法,调用一个静态方法就是“类名.方法名”
既然"无需本类的对象即可调用静态方法",而this和super关键字都是用于本类对象的-----调用静态方法无需本类的对象这句话很清楚表明:静态方法中不能用this和super关键字
-
- 5、静态方法是存放在内存中的数据段里,this和super调用的是堆空间里的应用对象不能调用数据段区域里的数据,因此静态方法中不能用this和super关键字
-
- 6、静态方法和静态类不属于单个对象,而是类的所有对象共享使用
而this代表当前对象
- 6、静态方法和静态类不属于单个对象,而是类的所有对象共享使用
-
- 7、东西只属于类,不属于任何对象,所以不能用THIS和SUPER。
- 9、条件运算符(三元运算符):
String type = score<60?"不及格":"及格";
int i = (string=="hello"? 10:-1);
int j = (x>0 ? 1:(x>10 ? 2:-1));//多重嵌套
- 10、 静态导入(static import)是在JDK1.5新增加的功能,其作用是用于导入制定类的静态属性,这样就可以直接使用静态属性;
import static java.lang.Math.PI; //导入Math类的PI属性
- 11、equals()方法提供定义“对象内容相等”的逻辑
- 12、数组的初始化方式:
-
静态初始化
int [] a = {1,2,5,7,3}; //静态初始化基本类型数组
User[] b = {
new User(01,"张三"),
new User(02,"李四"),
new User(03,"王五")
}; //静态初始化引用类型数组;
-
动态初始化
int[] a = new int[2]; //动态初始化数组,先分配空间;
a[0] = 1;//给数组元素赋值;
a[1] = 2;//给数组元素赋值;
-
默认初始化
int[] a = new int[2]; //默认值:0,0;
boolean[] b = new boolean[2]; //默认值:false,false;
String[] s = new String[2]; //默认值:null,null;
- 13、java虚拟机的内存可以分为三个区域:
-
栈stack
-
- 特点:
-
-
- (1)、栈描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法入口等);
-
-
-
- (2)、JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等);
-
-
-
- (3)、栈属于线程私有,不能实现线程间的共享;
-
-
-
- (4)、栈的存储特性是 先进后出,后进先出;
-
-
-
- (5)、栈是由系统自动分配,速度快,栈是一个连续的内存空间。
-
-
堆heap
-
- 特点:
-
-
- (1)、堆用于存储创建好的对象和数组(数组也是对象);
-
-
-
- (2)、JVM只有一个堆,被所有线程共享;
-
-
-
- (3)、堆是一个不连续的内存空间,分配灵活,速度慢。
-
-
方法区method area( 位于堆中)
-
- 特点:
-
-
- (1)、JVM只有一个方法区,被所有线程共享;
-
-
-
- (2)、方法区实际也是堆,只是用于存储类、常量相关的信息;
-
-
-
- (3)、用了存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)
-
- 14、当类中定义了有参构造方法,无参构造函数就不再存在,想要使用必须在类中显式声明;
- 15、继承使用要点:
-
- 父类也称作超类、基类等;
-
- java中只有单继承,没有C++那样的多继承。多继承会引起混乱,使得继承过于复杂,系统难于维护;
-
- java中类没有多继承,接口有多继承;
-
- 子类继承父类,可以得到父类的全部属性和方法(除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法);
-
- 如果定义一个类时,没有调用extends,则它的父类时:java.lang.Object。
- 16、instanceof运算符:
-
- instanceof是二元运算符,左边是对象,右边是类;当对象时右边类或子类所创建的对象时,返回true;否则,返回false。
```java
public class Test{
public static void main(String[] args) {
Student s = new Student();
System.out.println(s instanceof Person); //Student 继承自Person
System.out.println(s instanceof Student);
}
}
- instanceof是二元运算符,左边是对象,右边是类;当对象时右边类或子类所创建的对象时,返回true;否则,返回false。
```
- 17、逻辑运算符:
运算符 | 符号 | 说明 |
---|---|---|
逻辑与 | &(与) | 两个操作数为true,结果才为true,否则是false |
逻辑或 | !(或) | 两个操作数一个是true,结果就是true |
短路与 | &&(与) | 只要有一个为false,则直接返回false |
短路或 | ||(或) | 只要有一个为true,则直接返回true |
逻辑非 | !(非) | 取反:!false为true,!true为false |
逻辑异或 | ^(异或) | 相同则为false,不同为true |
-
短路与和短路或采用短路的方式,从左到右计算,如果只通过运算符左边的操作数就能确定该逻辑表达式的值,则不会继续计算运算符右边的操作数,提高效率。
- 18、递归结构
-
- 递归是一种常见的解决问题的方法,即把问题逐渐简单化。递归的基本思想就是“自己调用自己”,一个使用递归技术的方法将会直接或者间接的调用自己。
-
- 利用递归可以用简单的程序来解决一些复杂的问题。比如:斐波那契数列的计算、汉诺塔、快排等问题。
-
- 递归结构包括两个部分:
-
-
- (1)定义递归头。解答:什么时候不调用自身方法。如果没有头,将陷入死循环,也就是递归的结束条件。
-
-
-
- (2)递归体。解答:什么时候需要调用自身方法。
-
public class Test22{
public static void main(String[] args) {
long d1 = System.currentTimeMillis();
System.out.printf("%d阶乘的结果:%s%n",10,factorial(10));
long d2 = System.currentTimeMillis();
System.out.printf("递归费时:%s%n",d2-d1); //耗时:32ms
}
/** 求阶乘的方法*/
static long factorial(int n) {
if(n == 1) {//递归头
return 1;
}else{//递归体
return n*factorial(n - 1); //n! = n*(n - 1)!
}
}
}
-
- 递归的缺陷:
-
-
- 简单的程序是递归的有点之一,但是递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时,速度比循环慢得多,所以在使用递归时要慎重。
-
-
- 注意事项
-
-
- 任何能用递归解决的问题也能使用迭代(循环)解决。当递归方法可以增加自然地反映问题,并且易于理解和调试,并且不强调效率问题时,可以采用递归;
-
-
-
- 在要求高性能的情况下尽量避免使用递归,递归调用既花时间又耗内存。
-
- 19、向上自动转型,向上强制转型:
public class TestPolm {
public static void main(String[] args) {
Animal cat = new Cat();//自动向上转型
animalCry(cat);
Cat cat2 = (Cat)cat; //强制向下转型
}
static void animalCry(Animal a){
a.shut();
}
}
class Animal{
public void shut(){
System.out.println("叫了一下!");
}
}
class Dog extends Animal{//继承条件满足
public void shut(){//方法重写条件满足
System.out.println("汪汪汪");
}
}
class Cat extends Animal{//继承条件满足
public void shut(){//方法重写条件满足
System.out.println("喵喵喵");
}
}
原文地址:https://www.cnblogs.com/caoleiCoding/p/8947384.html
时间: 2024-10-09 16:48:54